如何删除给定内容类型的所有节点?


31

我有数千个特定内容类型的节点。使用网络界面(example.com/admin/content),一次只能删除约50个。如何快速删除它们?

Answers:


32

有一个用于该(TM)的模块。

请参阅批量删除

这将使用Batch API删除节点,以避免在一次调用node_delete_multiple()删除数千个节点时出现超时或内存问题。

批量删除是一个废弃的模块。请参阅替代品:


哇,我完全错过了这个。好发现。
格雷格

4
如果您要做的不仅仅是简单的内容类型过滤器,那么另一种方法可能会有用,那就是使用视图批量操作:drupal.org/project/views_bulk_operations
geerlingguy 2011年

批量删除模块现已废弃。建议在那里使用Views Bulk Operations。
Refineo 2011年

26

看一下Devel Generate模块的灵感,这是它的“内容杀死”功能devel_generate_content_kill

function devel_generate_content_kill($values) {
  $results = db_select('node', 'n')
              ->fields('n', array('nid'))
              ->condition('type', $values['node_types'], 'IN')
              ->execute();
  foreach ($results as $result) {
    $nids[] = $result->nid;
  }

  if (!empty($nids)) {
    node_delete_multiple($nids);
    drupal_set_message(t('Deleted %count nodes.', array('%count' => count($nids))));
  }
}

因此,我将尝试使用Devel Generate删除所有节点但不创建任何新节点,或者尝试使用example.com/devel/php devel_generate_content_kill(array('node_types' => array('my_node_type')));直接调用。


17

在Drupal 8中,一种方法是将EntityQuery()方法与EntityStorageInterface :: delete()方法一起使用:

$result = \Drupal::entityQuery("node")
    ->condition("type", "YOUR_CONTENT_TYPE_NAME")
    // If the update is being executed via drush entityQuery will only
    // return the content uid 0 have access to. To return all set
    // accessCheck to false since it defaults to TRUE. 
    ->accessCheck(FALSE)
    ->execute();

$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$entities = $storage_handler->loadMultiple($result);
$storage_handler->delete($entities);

如果您需要应用其他过滤器/条件,则可以查看QueryInterface界面页面

编辑(其他方式,感谢 @ 4k4):

$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$entities = $storage_handler->loadByProperties(["type" => "YOUR_CONTENT_TYPE_NAME"]);
$storage_handler->delete($entities);

如果要测试代码,可以使用:

drush php-eval '$storage_handler = \Drupal::entityTypeManager()->getStorage("node"); $entities = $storage_handler->loadByProperties(["type" => "article"]); $storage_handler->delete($entities);'

这将删除您的所有文章。


这是不正确的,delete()需要加载的实体,而不是ID的实体,这是实体查询返回的内容。代替使用非描述性的$ result,使用$ ids或$ nids,然后使用$ storage-> delete($ storage-> load($ ids))。
贝尔迪尔

@Berdir谢谢,我将再次测试代码,也许这个问题是在一次编辑中引入的
Adrian Cid Almaguer

@Berdir我更新了答案,并测试了代码,它可以工作,该问题是在一次编辑中引入的。
阿德里安·西德·阿尔玛格

2
@AdrianCidAlmaguer,您可以将查询替换为$entities = $storage_handler->loadByProperties(['type' => 'YOUR_CONTENT_TYPE_NAME']);
4k4,2016年

1
最近在更新挂钩中使用了此功能,值得注意的是,如果使用entityQuery accessCheck功能,则应在语句中设置。否则,如果您在drush中运行它,则默认情况下accessCheck设置为true,并且uid 0无权访问的任何节点都不会返回。
awm

13

如果只想通过UI进行操作,则可以使用devel_generate模块。

  1. 导航到“配置”(admin / config / development / generate / content)中的“ Generate Content”菜单。
  2. 选择要删除的内容类型。
  3. 确保选中“在生成新内容之前删除这些内容类型中的所有内容”旁边的复选框。
  4. 将您要生成的节点数设置为“ 0”。

这样,将不会生成任何节点,并且将删除所选类型的所有节点。


10

在drupal安装的根目录中使用以下代码创建一个文件,然后执行该文件。

<?php
  require_once './includes/bootstrap.inc';
  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

  $aquery= db_query("SELECT nid FROM {node} AS n WHERE n.type = 'company'");
  while ($row = db_fetch_object($aquery)) {
    node_delete($row->nid);
  }
?>

1
db_fetch_object不是D7数据库api的一部分。
ya.teck 2013年

10

您可以在Drupal 7中使用Devel模块的Execute PHP Code部分执行此操作,方法是输入:

$result= db_query("SELECT nid FROM {node} AS n WHERE n.type = 'TYPE'");
foreach ($result as $record) {
  node_delete($record->nid);
}

1
这将非常缓慢地执行,如果您需要删除数千个节点,最好使用使用批处理API的方法,例如VBO。
abielefeldt

6

如果使用Drush并删除所有模块,请在终端中执行以下操作:

 drush delete-all [content-type-machine-name]


Examples:
 drush delete-all article             Delect all article nodes.
 drush delete-all all                 Delete nodes of all types.
 drush delete-all --reset             Delete nodes of all types, and reset node, revision and comment counters.
 drush delete-all users               Delete users.

Options:
 --reset                              Reset counter for node, revision and comment tables.
 --roles                              pick roles

5

Views Bulk操作提供了启用BatchAPI的可配置节点管理屏幕,该屏幕允许按类型过滤,选择符合搜索条件的所有节点等。

那是我在Drupal 6中的实用解决方案-除了批量删除,您还可以批量编辑节点并做很多其他事情。

看来Drupal 7版本尚未准备好-但我会在D7发行版中关注该模块。


4

另一个代码段是:

$query = db_query("SELECT n.nid FROM {node} n WHERE n.type = 'TO_BE_DELETED'"); 
while ($n = db_fetch_object($query)) 
{
     node_delete($n->nid); 
} 

TO_BE_DELETED要删除的内容类型在哪里。


3
应该注意的是,仅适用于Drupal 4.6、5和6。Drupal 7版本是db_delete('node')
Greg


3

我使用Delete all module(删除所有模块),它与D8配合使用,并提供了非常有用的drush命令。例如,要删除article内容类型的所有内容:

drush delete-all article  

D8可以使用吗?我启用了该模块,但得到了找不到drush命令“删除所有文章”。我还清理了繁忙的缓存
Yassin Tahtah

1

您可以尝试 全部删除模块”,导航到“ admin / content / delete_content”,然后将显示一个表格,用于删除属于某些内容类型的内容。

问候




0

以编程方式删除内容类型的所有节点,这是一个帮助函数:


function _delete_all_nodes_of_type($type = '') {
  // Return all nids of nodes of type.
  $nids = db_select('node', 'n')
    ->fields('n', array('nid'))
    ->condition('n.type', $type)
    ->execute()
    ->fetchCol(); // returns an indexed array
  if (!empty($nids)) {
    node_delete_multiple($nids);
    drupal_set_message(format_plural(count($nids), count($nids) . ' node Deleted.', count($nids) . ' nodes Deleted.'));
  }
}


-1

我最终使用了db_delete,不需要任何模块:

<?php
  db_delete('node')
    ->condition('type', 'MY_CONTENT_TYPE')
    ->execute();
?>

编辑/警告:请参阅下面的Berdir评论。此方法不会清除与节点有关的所有数据。


3
这种方法的问题在于其他模块也无法做出反应并删除其信息。根据内容类型,该节点的content_type表中包含特定于节点的信息,字段,分类法(实际上也是一个字段),注释等。因此,您最终可能会在数据库中得到许多过时的信息。
贝尔迪尔2011年

@Berdir-有趣。有没有更好的内置方法来删除节点?
格雷格

3
有node_delete()和node_delete_multiple(),请参阅tim.plunket的答案,但这并非旨在处理数千个节点,请参阅api.drupal.org/api/drupal/modules--node--node.module/function /…。它加载所有节点,然后在单个请求中对其进行迭代。因此,如果要删除数百或数千个节点,则几乎必须使用诸如bulkdelete之类的contrib模块。
2011年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.