Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 如何获取集合中的最新文档并删除其他文档_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Mongodb 如何获取集合中的最新文档并删除其他文档

Mongodb 如何获取集合中的最新文档并删除其他文档,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我需要为每个用户获取集合中的最新文档(这里是通知),并删除其他文档。假设我有如下数据: [ { user: 1, time: ISODate("Mon, 14 Sep 2015 06:22:36 +0000"), msg: "message" }, { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" }, { user: 1, time: ISODate("Fri, 23

我需要为每个用户获取集合中的最新文档(这里是通知),并删除其他文档。假设我有如下数据:

[
    { user: 1, time: ISODate("Mon, 14 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Tue, 27 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 07:33:16 +0000"), msg: "message" }
]
[
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Tue, 27 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 07:33:16 +0000"), msg: "message" }
]
例如,我想获取最后两个通知并删除另一个,因此
user 1
的结果应该是:

[
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" }
]
数据如下所示:

[
    { user: 1, time: ISODate("Mon, 14 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Tue, 27 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 07:33:16 +0000"), msg: "message" }
]
[
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Tue, 27 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 07:33:16 +0000"), msg: "message" }
]
和属于
用户1
的其他记录将被删除。
那么,有效的方法是什么呢?

使用以下方法查找最后两个

 db.collection.find({user:1}).sort({time:-1}).limit(2)
使用以下命令删除除最后两个文档外的所有文档

var i = 0;
var user_ids = [];
db.users.find({user:1},{_id:1}).sort({time:-1}).forEach(function(user) {
    if(i>1)
    user_ids[i] = user._id;
   i++;
});
db.users.remove({_id: {$in: user_ids}})
没有直接的
方法
来删除除最后两个之外的所有
文档

但是如果您一次只想删除一个
文档
,那么您可以通过定义remove属性来使用
find和modify
函数,并将其设置为
true
我假设您的文档如下所示:

[
    { user: 1, time: ISODate("Mon, 14 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Tue, 27 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 07:33:16 +0000"), msg: "message" }
]
[
    { user: 1, time: ISODate("Tue, 15 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 1, time: ISODate("Fri, 23 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Tue, 27 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 06:22:36 +0000"), msg: "message" },
    { user: 2, time: ISODate("Wed, 28 Sep 2015 07:33:16 +0000"), msg: "message" }
]
{u id:ObjectId(“562b38f9d6995d3311d9ddce”),“用户”:1,“时间”:ISODate(“2015-09-14T06:22:36Z”),“消息”:“消息”}
{u id:ObjectId(“562b38f9d6995d3311d9ddcf”),“用户”:1,“时间”:ISODate(“2015-09-15T06:22:36Z”),“消息”:“消息”}
{u id:ObjectId(“562b38f9d6995d3311d9ddd2”),“用户”:2,“时间”:ISODate(“2015-09-28T06:22:36Z”),“消息”:“消息”}
{u id:ObjectId(“562b38f9d6995d3311d9ddd3”),“用户”:2,“时间”:ISODate(“2015-09-28T07:33:16Z”),“消息”:“消息”}
从中,您可以使用操作员为每个用户仅获取最后两个文档

var bulkOp=db.collection.initializeOrderedBulkOp();
var计数=0;
db.collection.aggregate([
{“$sort”:{“user”:1,“time”:-1},
{“$group”:{“\u id”:“$user”,“times”:{“$push”:“$time”}},
{“$project”:{
《泰晤士报》:{
“$slice”:[“$times”,2]
}
}}
]).forEach(功能(文档){
bulkOp.find({
“用户”:文件编号,
“时间”:{“$nin”:doc.times}
}).remove();
计数++;
如果(计数%100==0){
//每100次操作执行一次并重新初始化
bulkOp.execute();
bulkOp=db.collection.initializeOrderedBulkOp();
}
})
//清理队列
如果(计数>0){
bulkOp.execute();
}
在MongoDB 3.2之前,您需要通过
用户
编辑文档,然后使用返回
时间数组的运算符
。从那时起,您需要使用循环遍历聚合结果,然后通过首先按顺序排列
times
数组并使用方法返回最后两次。然后,您可以使用这些操作删除文档,以获得最大效率。当然,操作员允许您过滤旧文档

var bulkOp=db.collection.initializeOrderedBulkOp();
var计数=0;
db.collection.aggregate([
{“$组”:{
“_id”:“$user”,
“时间”:{“$push”:“$time”}
} }
]).forEach(函数(doc){
var times=doc.times.sort(函数(t1,t2){
返回t1t2-1:0);
}).reverse().slice(-2);
bulkOp.find({
“用户”:文件编号,
“时间”:{“$nin”:时间}
}).remove();
计数++;
如果(计数%100==0){
//每100次操作执行一次并重新初始化
bulkOp.execute();
bulkOp=db.collection.initializeOrderedBulkOp();
} 
})
//清理队列
如果(计数>0){
bulkOp.execute();
}

好吧,我知道如何获取这些,但我不知道如何删除另一个。您想在查找后删除所有文档,或删除除最后两个之外的所有文档我想删除属于
用户1的文档,但最后两个除外。不删除集合中的所有文档。是的,在上面的示例中,只应删除此文档
{user:1,time:ISODate(“Mon,2015年9月14日06:22:36+0000”),msg:“message”}
。如果我从
user 2
获取文档,则此文档
{user:2,time:ISODate(“周二,2015年9月27日06:22:36+0000”),msg:“message”}
将被删除。代码已编辑,请检查(我为mongo shell编写了代码,但您可以根据需要进行转换)如果我知道您想更新集合中的文档,并且只为每个用户保留最后两个文档。是吗?@user3100115是的,就是这样。在尝试了大约3M条记录后,这种方式要好得多。非常感谢你:D