我有一个存储邮件的集合,它看起来像这样:
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-May-15 3:30:05 PM),2日前4日(日期30-May-15 3:21:48 PM),3日前2日(日期30-May-15 3:20:00 PM) )。
我尝试了这个查询:
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));
});
此查询向我提供了某个人所说过的所有人,但它的顺序不正确,如果我更改了排序顺序,它会给我确切的结果。
如何按日期对收藏品进行排序?
答案 0 :(得分: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") }