如何删除mongodb中的N个文档

Yog*_*esh 42 mongodb

在我的集合中,文档包含类似状态和时间戳的关键字.当我想找到最新的十个文件时,我写下面的查询

db.collectionsname.find().sort({"timestamp"-1}).limit(10)
Run Code Online (Sandbox Code Playgroud)

这个查询给了我想要的结果,但是当我想删除最新的十个文档时,我正在编写以下查询

db.collectionsname.remove({"status":0},10).sort({"timestamp":-1})
Run Code Online (Sandbox Code Playgroud)

但它显示以下错误 TypeError: Cannot call method 'sort' of undefined ,我再次写下相同的查询 db.collectionsname.remove({"status":0},10) 它只删除一个文件.那么如何编写一个删除十个最新文档并按时间戳排序的查询?

Wir*_*rie 69

使用remove或时,您无法设置限制findAndModify.因此,如果要精确限制删除的文档数量,则需要分两步完成.

db.collectionName.find({}, {_id : 1})
    .limit(100)
    .sort({timestamp:-1})
    .toArray()
    .map(function(doc) { return doc._id; });  // Pull out just the _ids
Run Code Online (Sandbox Code Playgroud)

然后将返回的_ids 传递给remove方法:

db.collectionName.remove({_id: {$in: removeIdsArray}})
Run Code Online (Sandbox Code Playgroud)

仅供参考:您无法从上限集合中删除文档.

  • @ULazdins"Mongo在限制结果之前应用排序,无论你对光标进行排序和限制的顺序如何." ([源(http://stackoverflow.com/a/17509131/99777)) (10认同)
  • 如果我错了,请纠正我,但是`limit(100)`在`sort({timestamp:-1})之前或之后是否有所不同.在示例中,@ WiredPrairie将结果限制为100并在之后对它们进行排序(`.sort({timestamp:-1}).limit(100)`).在这种情况下,排序语句对返回的记录没有影响.另一方面,如果你要写`.limit(100).sort({timestamp:-1})`,它会有所作为. (2认同)

Ant*_*ley 11

您可以将 find 查询映射的输出流水线化以使用_id并根据$in查询执行删除,例如:

db.collection.remove({_id: 
    { $in: db.collection.find().sort({timestamp:-1}).limit(100).map(a => a._id) }
})
Run Code Online (Sandbox Code Playgroud)

  • 如果在“.map”之前添加“.toArray()”,循环依赖就会消失。 (3认同)
  • 在 MongoDB 5.0 上使用新的 mongo shell `mongosh` 会返回以下错误`错误:检测到循环依赖` (2认同)

Man*_*dey 10

要删除集合中的 N 个文档myCollection

db.getCollection('myCollection').find({}).limit(N).forEach(function(doc){
    db.getCollection('myCollection').remove({_id: doc._id});
})
Run Code Online (Sandbox Code Playgroud)

  • 与公认的答案相比,这在 Robo 3T 中对我来说非常有效。 (2认同)

deu*_*ine 7

令N为要删除的记录数。

    db.collectionName.find().limit(N).forEach(doc => 
     { 
       db.collectionName.remove({_id:doc._id})
     }
    )
Run Code Online (Sandbox Code Playgroud)

  • 它仍然是一个有用的答案。例如:- 当您在开发数据库中有大量文档并且您只想保留 4mi 中的 2mi 时,您可以让它过夜运行清理,而不是打印 2mi _id 然后提供它们(最有可能是分批) (3认同)
  • 恭喜,现在您有 N + 1 db 调用。 (2认同)

Mer*_*ury 5

工作解决方案(受到上面答案的启发):

(对于删除大量记录,$in操作员有限制,所以这是最终的解决方案)删除 1,000,000 条记录的示例

var ITERATIONS=1000;
var LIMIT=1000;
for(i=0; i<ITERATIONS; i++) {
    arr = db.MyCollection.find({}, {_id : 1}).limit(LIMIT).toArray().map(function(doc) { return doc._id; });
    db.MyCollection.remove({_id: {$in: arr}});
    // sleep(1);  // Optional for not loading mongo in case of huge amount of deletions
}
Run Code Online (Sandbox Code Playgroud)

您可以在 mongo shell 或 Robomongo 3T 中运行它