2015-11-06 43 views
1

我有一個具有以下結構的mongodb集合。MongoDB檢索與彙總字段相對應的子級文檔值

/* 0 */ 
{ 
    "_id" : ObjectId("5633cc4fd6f8ebfddf32fa77"), 
    "contact_name" : "Fred Flintstone", 
    "follow_up_date" : ISODate("2015-11-02T20:02:58.766Z"), 
    "notes" : [ 
     { 
      "author" : "Miles", 
     "note_date" : ISODate("2015-10-30T20:00:15.735Z"), 
     "note_text" : "Appointment requested via web interface", 
     "source_type" : "appointment_request" 
     }, 
     { 
      "author" : "John", 
     "note_date" : ISODate("2015-10-20T18:00:15.735Z"), 
     "note_text" : "Phone support ticket", 
     "source_type" : "web_support" 
     } 
    ] 
} 

/* 1 */ 
{ 
    "_id" : ObjectId("56381fe8d6f8ebfddf32fb8c"), 
    "contact_name" : "Barney Rubble", 
    "follow_up_date" : ISODate("2015-10-14T20:02:58.766Z"), 
    "notes" : [ 
     { 
      "author" : "John", 
     "note_date" : ISODate("2015-10-30T20:00:15.735Z"), 
     "note_text" : "Note entered", 
     "source_type" : "note" 
     }, 
     { 
      "author" : "John", 
     "note_date" : ISODate("2015-10-11T16:00:15.735Z"), 
     "note_text" : "Account created", 
     "source_type" : "account_activity" 
     } 
    ] 
} 

我想建立一個聚集查詢,這樣我檢索CONTACT_NAME,follow_up_date,最大notes.note_date和它對應notes.note_text和notes.source_type值。這是可能的做一個單一的電話來「聚合」?到目前爲止,我聚集管道設置如下:

[ 
    { 
     $unwind: "$notes" 
    }, 
    { 
     $group: { 
      _id: { 
       lead_id: "$_id", 
       contact_name: "$contact_name", 
       follow_up_date: "$follow_up_date" 
      }, 
      "num_entries": { "$sum": 1 }, 
      "last_entry": { "$max": "$notes.note_date" } 
     } 
    }, 
    { 
     $project: { 
      "contact_name": "$_id.contact_name", 
      "follow_up_date": "$_id.follow_up_date", 
      "last_entry": "$last_entry", 
      "num_entries": "$num_entries", 
      "lead_id": "$_id.lead_id" 
     } 
    } 
] 

這讓我我需要的一切,除了note_text和SOURCE_TYPE與「last_entry」一起去:{「$最大」:「$ notes.note_date」}值。這裏是正在返回:

[ 
    { 
     "_id": { 
      "lead_id": "563c69a4d6f8ebfddf32fce0", 
      "contact_name": "Barney Rubble", 
      "follow_up_date": "2015-10-14T20:02:58.766Z" 
     }, 
     "num_entries": 2, 
     "last_entry": "2015-10-30T20:00:15.735Z", 
     "contact_name": "Barney Rubble", 
     "follow_up_date": "2015-10-14T20:02:58.766Z", 
     "lead_id": "563c69a4d6f8ebfddf32fce0" 
    }, 
    { 
     "_id": { 
      "lead_id": "563c698fd6f8ebfddf32fcdf", 
      "contact_name": "Fred Flintstone", 
      "follow_up_date": "2015-11-02T20:02:58.766Z" 
     }, 
     "num_entries": 2, 
     "last_entry": "2015-10-30T20:00:15.735Z", 
     "contact_name": "Fred Flintstone", 
     "follow_up_date": "2015-11-02T20:02:58.766Z", 
     "lead_id": "563c698fd6f8ebfddf32fcdf" 
    } 
] 

而這正是我需要的:

[ 
    { 
     "_id": { 
      "lead_id": "563c69a4d6f8ebfddf32fce0", 
      "contact_name": "Barney Rubble", 
      "follow_up_date": "2015-10-14T20:02:58.766Z" 
     }, 
     "num_entries": 2, 
     "last_entry": "2015-10-30T20:00:15.735Z", 
     "last_entry_source_type": "appointment_request", 
     "last_entry_note_text": "Appointment requested via web interface", 
     "contact_name": "Barney Rubble", 
     "follow_up_date": "2015-10-14T20:02:58.766Z", 
     "lead_id": "563c69a4d6f8ebfddf32fce0" 
    }, 
    { 
     "_id": { 
      "lead_id": "563c698fd6f8ebfddf32fcdf", 
      "contact_name": "Fred Flintstone", 
      "follow_up_date": "2015-11-02T20:02:58.766Z" 
     }, 
     "num_entries": 2, 
     "last_entry": "2015-10-30T20:00:15.735Z", 
     "last_entry_source_type": "note", 
     "last_entry_note_text": "Note entered", 
     "contact_name": "Fred Flintstone", 
     "follow_up_date": "2015-11-02T20:02:58.766Z", 
     "lead_id": "563c698fd6f8ebfddf32fcdf" 
    } 
] 
+1

將是非常有益的,如果你可以編輯你的問題,包括從樣本數據的預期的結果。 – chridam

+0

增加了當前和期望的結果。 – Wake

回答

1

只想在$group管道之前推出$sort管道一步的重新排序的文檔流note_date鍵,然後您可以應用組累加器運算符$first$last,它們僅在文檔按照定義的順序時纔有意義。運營商將允許你提取整個denormalised文件,然後階段將做一些現場整形。

最終聚合管道會是什麼樣子:

[ 
    { 
     "$unwind": "$notes" 
    }, 
    { 
     "$sort": { "notes.note_date": 1 } 
    }, 
    { 
     "$group": { 
      "_id": { 
       "lead_id": "$_id", 
       "contact_name": "$contact_name", 
       "follow_up_date": "$follow_up_date" 
      }, 
      "num_entries": { "$sum": 1 }, 
      "last_entry": { "$last": "$notes" } 
     } 
    }, 
    { 
     "$project": { 
      "contact_name": "$_id.contact_name", 
      "follow_up_date": "$_id.follow_up_date", 
      "last_entry": "$last_entry.note_date", 
      "last_entry_source_type": "$last_entry.source_type", 
      "last_entry_note_text": "$last_entry.note_text", 
      "num_entries": 1, 
      "lead_id": "$_id.lead_id" 
     } 
    } 
]