I have about 13000 nodes to delete in a Drupal 7 site. I have tried the Views Bulk Operations module to delete 500 nodes at a time, but it times out. I can only delete 50 nodes at time.
How can I delete more than 50 nodes at time?
I have about 13000 nodes to delete in a Drupal 7 site. I have tried the Views Bulk Operations module to delete 500 nodes at a time, but it times out. I can only delete 50 nodes at time.
How can I delete more than 50 nodes at time?
VBO is the de facto standard for bulk-deleting nodes, there simply isn't a better way to do it.
As VBO processes in batches it only does 1 (or maybe a couple) of nodes at a time. So if you're receiving timeout errors those are related to the deletion of a single node, not to the entire batch operation.
The standard resolution to something like this is to increase the PHP max execution time to compensate.
Install Devel. Then go to admin/config/development/generate/content in D7 and select all content type. Check "Delete All content". Enter 0 in "How many nodes would you like to generate? "
Click Generate.
That'll delete all nodes.
generate-content
(genc
) command that comes with Devel Generate; drush help genc
for usage info.
Commented
Jun 14, 2013 at 15:00
Use a VBO and execute it from Drush. I used the following method to delete over 1.5million nodes after scale testing.
drush vbo-execute my_view action::views_bulk_operations_delete_item
Where, my_view is the machine name of your view
You can also use drush vbo-list to display all available views and their bulk operations.
The VBO should now run in the shell, giving you feedback as it goes.
There is a Delete All module out there. It will delete all the nodes and/or users from the site.
It also has Drush support:
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.
node_delete()
(it doesn't even bother to use node_delete_multiple()
). Even more worryingly, it has an option that deletes data directly from the database tables without using the field API, and without using hooks. No batch jobs at all, it just runs until the script dies. Very dangerous module IMHO.
drush delete-all article
to delete articles I'd go for this solution.
Use Views Bulk Operations - it was a good idea. But instead of calling operation directly, use batch api. Here you can read shor article about it. Lack of documentation on that part was a known problem.
For deleting nodes in large number(i.e is bulk) like in your case, you could also use Bulk delete module for this.
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().
Apart from this,you can even try Delete all module for deleting all the nodes of a content type.
Hope this helps.
You can also create batch process for it using BATCH API and in that batch process just do
foreach($nodes as $node){ node_delete($node[nid]);}
Thats it. You are done here. If you wish to create a drush command for it, you can also create it. For reference please look at this.
If you have reason to do it by code:
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->propertyOrderBy('nid', 'DESC')
->range(1000, 1000);
$result = $query->execute();
node_delete_multiple(array_keys($result['node']));
You also have many other available methods to select nodes to delete.
You can take Bobik's advise and feed that as the argument of a 'drush php-eval' if you're really in a pinch, but I would expect that the performance will be similar to that of VBO, while being slightly faster. If performance is really slow, you might wish to take a look at what modules are calling hook_node_delete by grepping the codebase for '_node_delete(' and then determining whether or not you can disable some of the modules which are using that hook.
On Drupal 8, an other way is to delete multiple entities without loading them all at a time but by chunk.
You can use less memory and have great performance :
$nids = \Drupal::entityQuery("node")
->condition("type", "my_bundle")
->execute();
$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
if (!empty($nids)) {
foreach (array_chunk($nids, 50) as $chunk) {
$nodes = $storage_handler->loadMultiple($chunk);
$storage_handler->delete($nodes);
}
};
For more convenience, you can trigger it inside drush command php-eval :
drush php-eval '$nids = \Drupal::entityQuery("node")->condition("type", "my_bundle")->execute(); $storage_handler = \Drupal::entityTypeManager()->getStorage("node"); if (!empty($nids)) { foreach (array_chunk($nids, 50) as $chunk) { $nodes = $storage_handler->loadMultiple($chunk); $storage_handler->delete($nodes); }};'