इसका सबसे सरल रूप है चीजों को "पैरामीटर" "नाम" द्वारा कुंजीबद्ध रखना:
db.collection.aggregate(
// Unwind the array
{ "$unwind": "$parameter"},
// Group on the "_id" and "name" and $sum "value"
{ "$group": {
"_id": {
"userId": "$userId",
"name": "$parameter.name"
},
"value": { "$sum": "$parameter.value" }
}},
// Put things into an array for "nice" processing
{ "$group": {
"_id": "$_id.userId",
"values": { "$push": {
"name": "$_id.name",
"value": "$value"
}}
}}
)
यदि आप वास्तव में फ़ील्ड मानों के रूप में नामों के "मान" रखने की आवश्यकता है, आप कर सकते हैं निम्नलिखित करें। लेकिन चूंकि आप फ़ील्ड/गुणों को "प्रोजेक्ट" कर रहे हैं, तो आपको उन सभी को अपने कोड में निर्दिष्ट करना होगा . अब आप "गतिशील" नहीं हो सकते हैं और आप कोडिंग/जेनरेट कर रहे हैं हर एक:
db.collection.aggregate([
// Unwind the array
{ "$unwind": "$parameter"},
// Group on the "_id" and "name" and $sum "value"
{ "$group": {
"_id": {
"userId": "$userId",
"name": "$parameter.name"
},
"value": { "$sum": "$parameter.value"}
}},
// Project out discrete "field" names with $cond
{ "$project": {
"name1": { "$cond": [
{ "$eq": [ "$_id.name", "name1" ] },
"$value",
0
]},
"name2": { "$cond": [
{ "$eq": [ "$_id.name", "name2" ] },
"$value",
0
]},
"name3": { "$cond": [
{ "$eq": [ "$_id.name", "name3" ] },
"$value",
0
]},
}},
// The $cond put "0" values in there. So clean up with $group and $sum
{ "$group": {
_id: "$_id.userId",
"name1": { "$sum": "$name1" },
"name2": { "$sum": "$name2" },
"name3": { "$sum": "$name3" }
}}
])
इसलिए जबकि अतिरिक्त कदम आपको वह परिणाम देते हैं जो आप चाहते हैं (अच्छी तरह से _id
को बदलने के लिए एक अंतिम परियोजना के साथ करने के लिए userId
), मेरे दिमाग के लिए लघु संस्करण पर्याप्त रूप से व्यावहारिक है, जब तक कि आपको वास्तव में इसकी आवश्यकता न हो। वहां से भी आउटपुट पर विचार करें:
{
"_id" : ObjectId("53245016ea402b31d77b0372"),
"values" : [
{
"name" : "name3",
"value" : 2
},
{
"name" : "name2",
"value" : 0
},
{
"name" : "name1",
"value" : 150
}
]
}
तो यही वह होगा जो मैं व्यक्तिगत रूप से उपयोग करूंगा। लेकिन आपकी पसंद।