2015-05-30 82 views
2

我在那里我存储的信息的集合,它看起来像这样:如何在使用MongoDB聚合框架的组中找到最近的项目?

id sender receiver date 
------------------------ 
1  1  2 30-May-15 3:14:48 PM 
2  2  1 30-May-15 3:16:28 PM 
3  1  3 30-May-15 3:20:00 PM 
4  1  2 30-May-15 3:21:48 PM 
5  3  2 30-May-15 3:25:15 PM 
6  4  1 30-May-15 3:30:05 PM 

发件人包含谁发送的消息和接收器包含谁将会收到它的人的ID的人的ID。

我想创建一个最近的联系人列表。也就是说,找到某个人说过的所有人(作为发件人或收件人),按日期排序。如果重复,我只需要保留最近的联系人。

例如:如果我搜索与ID = 1的人交谈的人,我想获得以下人员ID:4,2,3(与他讲话的人):4是最新的人(日期为30日至5月15日3点30分5秒),2日为4日(日期为15日至15日3点21分48秒),3日为2日(日期为15日至15日3点20分下午)。

我尝试此查询:

messages.aggregate({$match: {$or:[{sender: searched_id}, {receiver: searched_id}]}}, 
       {$sort: {date: -1}}, 
       {$group: {"_id": {sender: "$sender", receiver: "$receiver"}}}, 
        function(err, docs){ 
    console.log(JSON.stringify(docs)); 
}); 

该查询给了我所有谁某某人所讲的人,但它不是以正确的顺序,如果我更改排列顺序,它给我的确切的结果。

我该如何按日期对我的收藏进行分类?

+2

我不明白为什么你需要的* $组*参数。你的$匹配和$排序工作得很好。 –

+0

@ThomasBormans,因为我只需要有一次id,所以我认为按2个字段分组将会产生不同的id。我试图删除$ group参数,它给了我一些我甚至没有收集到的id。 –

+0

_“它给了我一些我甚至没有收集到的id”_没有办法让'$ match'或'$ sort'来“生成”新的id - 也不会产生重复的id。 '$ match'将一个输入文档映射到零或一个输出文档。 '$ sort'将一个输入文档映射到一个输出文档。无论如何,它们都不会改变文件。 –

回答

1

考虑到数据集:

{ "_id" : 1, "sender" : 1, "receiver" : 2, "date" : ISODate("2015-05-30T15:14:48Z") } 
{ "_id" : 2, "sender" : 2, "receiver" : 1, "date" : ISODate("2015-05-30T15:16:28Z") } 
{ "_id" : 3, "sender" : 1, "receiver" : 3, "date" : ISODate("2015-05-30T15:20:00Z") } 
{ "_id" : 4, "sender" : 1, "receiver" : 2, "date" : ISODate("2015-05-30T15:21:48Z") } 
{ "_id" : 5, "sender" : 3, "receiver" : 2, "date" : ISODate("2015-05-30T15:25:15Z") } 
{ "_id" : 6, "sender" : 4, "receiver" : 1, "date" : ISODate("2015-05-30T15:30:05Z") } 

可以明显地要只保留最近接触,您可以通过使用达到您想要的结果:

> searched_id = 1 
> db.test.aggregate([ 
{$match: {$or: [{sender: searched_id}, {receiver: searched_id}]}}, 
{$project: { _id: 1, date: 1, 
       interlocutor: {$cond: [{$eq: ["$sender", searched_id]},"$receiver","$sender"]}}}, 
{$group: {_id: "$interlocutor", date: {$max: "$date"}}}, 
{$sort: {date: -1}}, 
]) 
  • $match阶段是一个简单的过滤器;
  • $project阶段将推断对话者作为发送者或接收者;
  • $group阶段将对每个对话者分组多个结果,在每个组中保留最近呼叫日期($max);
  • 最后一个$sort阶段将结果文档从最多到最近排序。

运行这条管道,它将返回:

{ "_id" : 4, "date" : ISODate("2015-05-30T15:30:05Z") } 
{ "_id" : 2, "date" : ISODate("2015-05-30T15:21:48Z") } 
{ "_id" : 3, "date" : ISODate("2015-05-30T15:20:00Z") } 
+0

它的工作原理!非常感谢你! :) –

相关问题