I have several thousand nodes of a particular content type. Using the web interface (example.com/admin/content), I can only delete about 50 at a time. How can I quickly delete them?
19 Answers
There is a module for that (TM).
See Bulk Delete.
That will use the Batch API to delete the nodes to avoid timeout or memory issues when deleting thousands of nodes with a single call to node_delete_multiple().
Bulk Delete is an abandoned module. See for alternatives:
In Drupal 8 one way is use the entityQuery() method with the EntityStorageInterface::delete() method:
$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);
If you need to apply other filters/conditions you can check the QueryInterface interface page
EDIT (Other way, thanks to @4k4):
$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$entities = $storage_handler->loadByProperties(["type" => "YOUR_CONTENT_TYPE_NAME"]);
$storage_handler->delete($entities);
If you want to test the code you can use:
drush php-eval '$storage_handler = \Drupal::entityTypeManager()->getStorage("node"); $entities = $storage_handler->loadByProperties(["type" => "article"]); $storage_handler->delete($entities);'
This will delete all your articles.
Looking at the Devel Generate module for inspiration, here is its "content kill" function 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)))); } }
So I would try either using Devel Generate to delete all nodes but create no new ones, or use example.com/devel/php to call devel_generate_content_kill(array('node_types' => array('my_node_type')));
directly.
If you want to do it purely through the UI, you can use the devel_generate module.
- Navigate to the "Generate Content" menu in "Configuration" (admin/config/development/generate/content).
- Select the content types you want to delete.
- Make sure the checkbox next to "Delete all content in these content types before generating new content" is checked.
- Set the number of nodes you'd like to generate to "0".
This way, no nodes will be generated and all nodes of the selected types will be deleted.
You can do this is in Drupal 7 using the Execute PHP Code part of the Devel module by entering:
$result= db_query("SELECT nid FROM {node} AS n WHERE n.type = 'TYPE'");
foreach ($result as $record) {
node_delete($record->nid);
}
-
1This will execute very slowly, if you need to delete thousands of nodes it's better to use a method which uses the batch API such as VBO. Commented Mar 14, 2017 at 15:47
Create a file with below code in root of drupal installation and execute the file.
<?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
Do this in terminal, if you use Drush and the delete all module:
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
-
The drush command doesn't work when I use a subsite: drush -l my_site delete-all-delete-content -y but deleting from the ui works >> /admin/content/delete_content. Commented Mar 16, 2022 at 8:56
Views Bulk operations provides a BatchAPI enabled, configurable node admin screen that allows filtering by type, selection of all nodes matching your search criteria, etc.
That's my hands-down solution in Drupal 6 - besides batch delete, you can bulk-edit nodes and do a bunch of other stuff.
It looks like the Drupal 7 version isn't ready yet - but I'd be watching that module for a D7 release.
With Devel module, using drush:
drush genc 0 --types=article --kill
Or in UI as explained here: http://befused.com/drupal/delete-nodes-devel
-
It's the Devel sub-module
devel_generate
that needs to be enabled. And for multiple types it'sdrush genc 0 --kill --types="article, page"
– leymannxCommented Nov 21, 2018 at 21:39
Another snippet is:
$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);
}
where TO_BE_DELETED
is the content type to be deleted.
-
3It should be noted that works for Drupal 4.6, 5, and 6 only. The Drupal 7 version is
db_delete('node')
– GregCommented Mar 10, 2011 at 4:44
I use Delete all module, it works fine with D8 and provides very useful drush commands. For example, to delete all content of the article
content type:
drush delete-all article
-
1Does this work with D8? I enabled the module but I get The drush command 'delete-all article' could not be found. I also cleared the drush cache Commented Jan 11, 2017 at 14:39
-
You can try Delete all module, navigate to 'admin/content/delete_content' and you will be presented with a form for deletion of content belonging to certain content types.
Regards
If you have Migrate module enabled you can use:
$ drush migrate-wipe <content-type>
In newer versions of Drush, you can use the entity:delete
command to bulk delete nodes of a specific content type. No contributed modules or custom functions are required.
drush entity:delete node --bundle=content_type_machine_name
Another use of this command is to delete specific nodes. For example, to delete nodes 14, 16, 382, and 596, structure your command like this:
drush entity:delete node 14,16,382,596
More information can be found in the Drush documentation.
This module is used to delete all content and/or users from a site. This is mainly a developer tool, which can come in handy in several case
https://www.drupal.org/project/delete_all
as will as the Bulk Delete module will delete any nodes of a certain node-type using the batch api. It is advised to use the Views Batch Operations module (VBO) for a small number of nodes. But if you have to delete 10.000 nodes this module might be a better option.
Delete all nodes of content type programmatically here is a helper function:
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.'));
}
}
Not sure if this is fast but if you wanted to get feedback about which node it was deleting you could do something like this:
<?php
$nids = \Drupal::entityQuery('node')->condition('type','output')->execute();
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
foreach ($nodes as $n) {
echo $n->id() . "\n";
$n->delete();
}
You can rush it with something like drush scr del.php
. The nid would be displayed right before it was deleted.
This is the most direct way but it has issues when you have a considerable amount of data.
$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$entities = $storage_handler->loadByProperties(["type" => "YOUR_CONTENT_TYPE_NAME"]);
$storage_handler->delete($entities);
To avoid this problem you could retrieve every node id by applying an entity query search and then doing each node deletion inside a for-each loop.
$query = \Drupal::entityQuery('node')->condition('type', 'YOUR_CONTENT_TYPE_NAME');
$nids = $query->execute();
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
foreach ($nodes as $n) {
$n->delete();
}
You can even play around adding any conditions to the query by keep calling the method condition('field_to_evaluate', 'value')
(API docs).
Bonus
To execute from drush cli:drush eval "
\$query = \\Drupal::entityQuery('node')
->condition('type', 'YOUR_CONTENT_TYPE_NAME');
\$nids = \$query->execute();
\$nodes = \\Drupal::entityTypeManager()->getStorage('node')->loadMultiple(\$nids);
foreach (\$nodes as \$n) {
\$n->delete();
echo 'Deleted node ' . \$n->id() . PHP_EOL;
}
"
If you run into memory issues try to add php -d memory_limit=-1
before the drush command
Happy coding!
I ended up using db_delete, no modules required:
<?php
db_delete('node')
->condition('type', 'MY_CONTENT_TYPE')
->execute();
?>
Edit/Warning: See Berdir's comment below. This method does not clean up all data related to the nodes.
-
3The problem with this approach is that other modules are not able to react and delete their information too. Depending on the content type, there is node specific information in the content_type table of that node, fields, taxonomies (a field too, actually), comments and so on. So you possibly end up with a lot of stale information in your database.– BerdirCommented Mar 9, 2011 at 17:47
-
@Berdir - Interesting. Is there a better built-in way to delete nodes?– GregCommented Mar 9, 2011 at 17:56
-
3There is node_delete() and node_delete_multiple(), see tim.plunket's answer, but that isn't designed to handle thousands of nodes, see api.drupal.org/api/drupal/modules--node--node.module/function/…. It loads all nodes and then iterates over them in a single request. So pretty much have to use a contrib module like bulkdelete if you want to delete hundreds or thousands of nodes.– BerdirCommented Mar 9, 2011 at 18:20