我想从一个集合中删除大量旧文档,因此使用批量api是有意义的.删除它们很简单: var bulk = db.myCollection.initializeUnorderedBulkOp();bulk.find({ _id: { $lt: oldestAllowedId }}).remove();bulk.execute(); 唯一的问
var bulk = db.myCollection.initializeUnorderedBulkOp(); bulk.find({ _id: { $lt: oldestAllowedId } }).remove(); bulk.execute();
唯一的问题是这将尝试删除符合此条件的每个文档,在这种情况下是数百万个文档,因此出于性能原因,我不想一次删除它们.我想对操作强制执行限制,以便我可以执行诸如bulk.limit(10000).execute();并将操作间隔几秒钟,以防止将数据库锁定的时间超过必要的时间.但是,我无法找到任何可以传递给批量的选项来限制它执行的数量.
有没有办法以这种方式限制批量操作?
在任何人提到它之前,我知道批量会自动将操作拆分为1000个文档块,但它仍然会尽可能快地按顺序执行所有这些操作.这导致了比我现在可以处理的更大的性能影响.
您可以使用.forEach
方法迭代与您的查询匹配的那些文档的_id数组.返回该数组的最佳方法是使用
.distinct()
方法.然后使用
“bulk”操作删除文档.
var bulk = db.myCollection.initializeUnorderedBulkOp(); var count = 0; var ids = db.myCollection.distinct('_id', { '_id': { '$lt': oldestAllowedId } } ); ids.forEach(function(id) { bulk.find( { '_id': id } ).removeOne(); count++; if (count % 1000 === 0) { // Execute per 1000 operations and re-init bulk.execute(); // Here you can sleep for a while bulk = db.myCollection.initializeUnorderedBulkOp(); } }); // clean up queues if (count > 0 ) { bulk.execute(); }