2015-05-30 106 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

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

相關問題