我收集了一些包含以下字段的消息:_id
,senderId
,receiverId
,dateSubmittedMs
,message
,并且对于给定的用户我想要从所有其他用户返回最新消息给他。所以,例如,如果有Alex,Barb,Chuck,Dora的用户,我想返回Alex和Barb,Chuck和Dora之间的最新消息。做这个的最好方式是什么?我可以使用聚合一步完成吗?
官方在线文档(http://docs.mongodb.org/manual/reference/aggregation/min/)中的聚合示例显示了如何找到集合中组的最低年龄,但我需要的是类似于找到最年轻人的名字而不是人群。
这是我目前的做法:
步骤1:查找Alex发送和接收的所有邮件的dateSubmitted
的最高值,并对其他用户进行分组:
var M = Messages.aggregate(
{$match:
{$or: [{senderId: 'Alex'}, {receiverId: 'Alex'}]}
},
{$group: {_id: "$receiverId", lastestSubmitted: {$max: "$submitted"} }}).fetch();
步骤2:创建dateSubmitted的最高值的数组:
var MIds = _.pluck(M,'lastestSubmitted');
步骤3:通过senderId,receiverId和latestSubmitted:
查找这些消息return Messages.find(
{submitted: {$in: MIds}, $or: [{senderId: 'Alex'}, {receiverId: 'Alex'}]},
{$sort: {submitted: 1}}
});
这有两个问题:
receiverId: 'Alex'
之类的内容进行分组,而不是仅对$or [{receiverId: 'Alex', senderId: 'Barb'}, {senderId: 'Alex', receiverId: 'Barb'}]
进行分组? (但对于其他每个用户)这将允许我在Alex与之交谈的任何两个参与者之间的对话中获取最新消息。例如:有什么建议吗?
答案 0 :(得分:1)
你唯一需要改变的是灌浆阶段的group._id。虽然您可以将文档用于此建议而不仅仅是字段,但您可以在同一管道中应用排序。但是,如果仅使用receiverId进行分组,则不会发生变化。
var M = Messages.aggregate(
{$match:
{$or: [{senderId: 'Alex'}, {receiverId: 'Alex'}]}
},
{$group:
{_id: {
receiverId: "$receiverId",
senderId: "$senderId"},
lastestSubmitted: {$max: "$submitted"} }
},
{$sort: {submitted: -1}
},
{$limit: 1}
).fetch();
上面的这个例子只增加了检查第二个最近ping通连接或第三个连接的可能性,如果你只能获得你甚至不需要分组的最新消息。跑吧:
var M = Messages.aggregate(
{$match:
{$or: [{senderId: 'Alex'}, {receiverId: 'Alex'}]}
},
{$sort: {submitted: -1}
},
{$limit: 1}
).fetch();
上述答案是为了获得单个用户和其他用户之间最近的消息,在所有涉及用户阅读的对话之间获得最近的消息>>>
根据评论,我误解了一些问题,但无论如何,上面的部分是有用的。正确解决您的问题。在这种情况下,困难在于获得该对的密钥以进行分组并识别切换对(bob - > tom == tom - > bob)。你可以使用条件和排序来识别掉期。 (这肯定是一个更难的问题)代码看起来像这样:
var M = Messages.aggregate(
{$match:
{$or: [{senderId: 'Alex'}, {receiverId: 'Alex'}]}
},
{$project:
{'part1':{$cond:[{$gt:['$senderId','$receiverId']},'$senderId','$receiverId']},
'part2':{$cond:[{$gt:['$senderId','$receiverId']},'$receiverId','$senderId']},
'message':1,
'submitted':1
}
},
{$sort: {submitted: -1}},
{$group:
{_id: {
part1: "$part1",
part2: "$part2"},
lastestSubmitted: {$first: "$submitted"},
message: {$first: "$message"} }
}
).fetch();
如果您不熟悉上面使用的某些运算符,例如$ cond或$ first,请查看this。