我有一个具有以下结构的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”:{“$ max”:“$ 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"
}
]
答案 0 :(得分:1)
在 $sort
管道之前引入 $group
管道步骤,以便通过note_date
键对文档流进行重新排序然后,您可以应用组累加器运算符 $first
或 $last
,这些只有在文档按定义的顺序时才有意义。运算符将允许您提取整个非规范化notes
文档,然后 $project
阶段将进行一些字段重新整形。
最终的聚合管道如下所示:
[
{
"$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"
}
}
]