65

在我的收藏中,文档包含状态和时间戳等键。当我想查找最新的十个文档时,我会编写以下查询

db.collectionsname.find().sort({"timestamp"-1}).limit(10)

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

db.collectionsname.remove({"status":0},10).sort({"timestamp":-1})

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

4

10 回答 10

92

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

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

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

db.collectionName.remove({_id: {$in: removeIdsArray}})

仅供参考:您不能从上限集合中删除文档。

于 2013-09-28T11:15:21.153 回答
24

设 N 为要删除的记录数。

    db.collectionName.find().limit(N).forEach(doc => 
     { 
       db.collectionName.remove({_id:doc._id})
     }
    )
于 2018-12-27T12:32:39.800 回答
16

您可以管道查找查询映射的输出以使用_id和执行基于$in查询的删除,例如:

db.collection.remove({_id: 
    { $in: db.collection.find().sort({timestamp:-1}).limit(100).map(a => a._id) }
})
于 2020-03-19T16:34:00.100 回答
10

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

db.getCollection('myCollection').find({}).limit(N).forEach(function(doc){
    db.getCollection('myCollection').remove({_id: doc._id});
})
于 2019-04-02T09:42:46.310 回答
1

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

(删除大量记录$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
}

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

于 2020-08-04T09:32:36.980 回答
0

这是另一种方法:

步骤 1:对临时集合中的文档进行排序和限制以及 $out

db.my_coll.aggregate([
  { $sort: { _id: - 1} },
  { $limit: 10000 },
  { $out: 'my_coll_temp' }
])

第 2 步:从原始集合中删除(不删除,因为这会保留索引)所有文档。此外,这一步可能会使这种方法的通用性降低,因为移除可能并不总是可能的。

db.my_coll.remove({})

步骤 3:将文档从临时集合移回原始集合

db.my_coll_temp.aggregate([ { $out: 'my_coll' } ])

第 4 步:删除临时集合

db.my_coll_temp.drop()
于 2020-06-11T14:56:52.383 回答
0

我找到的方法是:

        let uid = "your_user";

        let a = await db
          .collection(`notifications`)
          .find({
            owner: uid,
          })
          .sort({ _id: -1 })
          .skip(1000)
          .limit(1)
          .toArray();

        if (a.length > 0) {
          let _id = new ObjectId(a[0]._id);
          db.collection(
            `notifications`
          ).deleteMany({
            owner: uid,
            _id: { $lt: _id },
          });
        }

说明:“a”变量获取您要删除的最后一个条目的 _id。您可以使用“跳过”指定 n 值。示例:您有 5000 个条目,但您想保留 400 个新条目,只需将跳过设置为“400”。在这种情况下,我们按 _id 排序,但你可以使用你想要的。您可以使用 find 过滤结果以完全匹配您需要的内容。

算法的后半部分进行删除。使用相同的过滤器(所有者:uid)来匹配第一个查找,并删除许多小于“_id”的内容。

您还可以在此代码块之前使用 'count' if 语句来检查是否有必要,以避免服务器滑行。

于 2022-01-10T19:14:12.120 回答
-1

另一种方法是编写 python 脚本。

from pymongo import MongoClient

def main():
    local_client = MongoClient()
    collection = local_client.database.collection
    cursor = collection.find()
    total_number_of_records = 10000

    for document in cursor:
        id = document.get("_id")

        if total_number_of_records == 100:
            break

        delete_query = {"_id": id}
        collection.delete_one(delete_query)

        total_number_of_records -= 1

if __name__ == "__main__":
    # execute only if run as a script
    main()
于 2018-11-20T18:40:08.090 回答
-6

查询sql是

db.order.find({"业务员姓名" : "吊炸天"},{"业务员编号":0}).sort({ "订单时间" : -1 })

结果是

{
"_id" : ObjectId("5c9c875fdadfd961b4d847e7"),
"推送ID" : "248437",
"订单时间" : ISODate("2019-03-28T08:35:52Z"),
"订单状态" : "1",
"订单编号" : "20190328163552306694",
"业务员姓名" : "吊炸天"
}
{
"_id" : ObjectId("5c9c875fdadfd961b4d847e8"),
"推送ID" : "248438",
"订单时间" : ISODate("2019-03-28T08:35:52Z"),
"订单状态" : "1",
"订单编号" : "20190328163552178132",
"业务员姓名" : "吊炸天"
}
{
"_id" : ObjectId("5c9c875fdadfd961b4d847e5"),
"推送ID" : "248435",
"订单时间" : ISODate("2019-03-28T08:35:51Z"),
"订单状态" : "1",
"订单编号" : "20190328163551711074",
"业务员姓名" : "吊炸天"
}
{
"_id" : ObjectId("5c9c875fdadfd961b4d847e6"),
"推送ID" : "248436",
"订单时间" : ISODate("2019-03-28T08:35:51Z"),
"订单状态" : "1",
"订单编号" : "20190328163551758179",
"业务员姓名" : "吊炸天"
}

现在删除3和4数据

var name = ["吊炸天"]
var idArray = db.order.find({"业务员姓名" : {$in:name}},{"订单编号":1,})
                .sort({ "订单时间" : -1 })
                .skip(2)
                .map(function(doc){return doc.订单编号})

db.order.deleteMany({"订单编号":{$in:idArray}})

返回结果是

{
"acknowledged" : true,
"deletedCount" : 2
}
于 2019-03-28T09:16:32.087 回答
-7

下面的查询将从集合中查找并删除最新的 10 个文档:-

db.collectionsname.findAndModify({
    query: { 'status':0 },
    sort: { 'timestamp': -1 },
    limit: 10,
    remove: true
});
于 2017-04-12T05:31:07.027 回答