यह वास्तव में काफी आसान है, प्रत्येक सरणी के परिणामों को योग करने के लिए यह केवल समझदार की बात है कि कौन सा और "तत्वों का संयोजन" है। संक्षेप में, आपको शायद इसे अपने दस्तावेज़ों में वैसे भी करना चाहिए जैसा कि पहले पाइपलाइन चरण (चरणों) से स्पष्ट होना चाहिए।
तो MongoDB 2.6 और इससे अधिक के लिए कुछ सहायक तरीके हैं:
db.events.aggregate([
{ "$project": {
"app_id": 1,
"event_count": 1,
"all_events": {
"$setUnion": [
{ "$map": {
"input": "$events",
"as": "el",
"in": {
"type": "$$el.type",
"value": "$$el.value",
"class": { "$literal": "A" }
}
}},
{ "$map": {
"input": "$unique_events",
"as": "el",
"in": {
"type": "$$el.type",
"value": "$$el.value",
"class": { "$literal": "B" }
}
}}
]
}
}},
{ "$unwind": "$all_events" },
{ "$group": {
"_id": {
"app_id": "$app_id",
"class": "$all_events.class",
"type": "$all_events.type"
},
"event_count": { "$sum": "$event_count" },
"value": { "$sum": "$all_events.value" }
}},
{ "$group": {
"_id": "$_id.app_id",
"event_count": { "$sum": "$event_count" },
"events": {
"$push": {
"$cond": [
{ "$eq": [ "$_id.class", "A" ] },
{ "type": "$_id.type", "value": "$value" },
false
]
}
},
"unique_events": {
"$push": {
"$cond": [
{ "$eq": [ "$_id.class", "B" ] },
{ "type": "$_id.type", "value": "$value" },
false
]
}
}
}},
{ "$project": {
"event_count": 1,
"events": { "$setDifference": [ "$events", [false] ] },
"unique_events": {
"$setDifference": [ "$unique_events", [false] ]
}
}}
])
अधिकतर $setUnion
में
और $setDifference
ऑपरेटरों। दूसरा मामला है $map
, जो जगह में सरणियों को संसाधित करता है। के उपयोग के बिना सरणियों पर संचालन करना पूरी बात है $unwind
. लेकिन वे निश्चित रूप से पूर्व संस्करणों में किए जा सकते हैं, इसमें थोड़ा और काम लगता है:
db.events.aggregate([
{ "$unwind": "$events" },
{ "$group": {
"_id": "$_id",
"app_id": { "$first": "$app_id" },
"event_count": { "$first": "$event_count" },
"events": {
"$push": {
"type": "$events.type",
"value": "$events.value",
"class": { "$const": "A" }
}
},
"unique_events": { "$first": "$unique_events" }
}},
{ "$unwind": "$unique_events" },
{ "$group": {
"_id": "$_id",
"app_id": { "$first": "$app_id" },
"event_count": { "$first": "$event_count" },
"events": { "$first": "$events" },
"unique_events": {
"$push": {
"type": "$unique_events.type",
"value": "$unique_events.value",
"class": { "$const": "B" }
}
}
}},
{ "$project": {
"app_id": 1,
"event_count": 1,
"events": 1,
"unique_events": 1,
"type": { "$const": [ "A","B" ] }
}},
{ "$unwind": "$type" },
{ "$unwind": "$events" },
{ "$unwind": "$unique_events" },
{ "$group": {
"_id": "$_id",
"app_id": { "$first": "$app_id" },
"event_count": { "$first": "$event_count" },
"all_events": {
"$addToSet": {
"$cond": [
{ "$eq": [ "$events.class", "$type" ] },
{
"type": "$events.type",
"value": "$events.value",
"class": "$events.class"
},
{
"type": "$unique_events.type",
"value": "$unique_events.value",
"class": "$unique_events.class"
}
]
}
}
}},
{ "$unwind": "$all_events" },
{ "$group": {
"_id": {
"app_id": "$app_id",
"class": "$all_events.class",
"type": "$all_events.type"
},
"event_count": { "$sum": "$event_count" },
"value": { "$sum": "$all_events.value" }
}},
{ "$group": {
"_id": "$_id.app_id",
"event_count": { "$sum": "$event_count" },
"events": {
"$push": {
"$cond": [
{ "$eq": [ "$_id.class", "A" ] },
{ "type": "$_id.type", "value": "$value" },
false
]
}
},
"unique_events": {
"$push": {
"$cond": [
{ "$eq": [ "$_id.class", "B" ] },
{ "type": "$_id.type", "value": "$value" },
false
]
}
}
}},
{ "$unwind": "$events" },
{ "$match": { "events": { "$ne": false } } },
{ "$group": {
"_id": "$_id",
"event_count": { "$first": "$event_count" },
"events": { "$push": "$events" },
"unique_events": { "$first": "$unique_events" }
}},
{ "$unwind": "$unique_events" },
{ "$match": { "unique_events": { "$ne": false } } },
{ "$group": {
"_id": "$_id",
"event_count": { "$first": "$event_count" },
"events": { "$first": "$events" },
"unique_events": { "$push": "$unique_events" }
}}
])
यह आपको वह परिणाम देता है जो आप चाहते हैं कि प्रत्येक सरणी एक साथ "सारांशित" हो और साथ ही मास्टर "event_count" सही परिणाम के साथ हो।
आपको शायद उन दोनों सरणियों को एक समान पहचानकर्ता के साथ संयोजन करने पर विचार करना चाहिए जो कि प्रदर्शित किए गए पाइपलाइनों में उपयोग किया गया है। यह हिस्सा काम का आधा है। दूसरा आधा इस बात पर विचार कर रहा है कि आपको सर्वोत्तम एप्लिकेशन प्रदर्शन के लिए कहीं संग्रह में पूर्व-एकत्रित परिणामों को संग्रहीत करना चाहिए।