MongoDB 3.4 और नए में एकत्रीकरण ढांचा $reduce
की पेशकश करता है ऑपरेटर जो अतिरिक्त पाइपलाइनों की आवश्यकता के बिना कुशलता से कुल गणना करता है। कुल रेटिंग वापस करने के लिए इसे एक अभिव्यक्ति के रूप में उपयोग करने पर विचार करें और $size
का उपयोग करके रेटिंग की संख्या प्राप्त करें . साथ में $addFields
, इस प्रकार औसत की गणना अंकगणितीय ऑपरेटर का उपयोग करके की जा सकती है $divide
जैसा कि सूत्र में है average = total ratings/number of ratings
:
db.collection.aggregate([
{
"$addFields": {
"rating_average": {
"$divide": [
{ // expression returns total
"$reduce": {
"input": "$ratings",
"initialValue": 0,
"in": { "$add": ["$$value", "$$this.rating"] }
}
},
{ // expression returns ratings count
"$cond": [
{ "$ne": [ { "$size": "$ratings" }, 0 ] },
{ "$size": "$ratings" },
1
]
}
]
}
}
}
])
नमूना आउटपुट
{
"_id" : ObjectId("58ab48556da32ab5198623f4"),
"title" : "The Hobbit",
"ratings" : [
{
"title" : "best book ever",
"rating" : 5.0
},
{
"title" : "good book",
"rating" : 3.5
}
],
"rating_average" : 4.25
}
पुराने संस्करणों के साथ, आपको पहले $unwind
. लागू करना होगा ratings
. पर ऑपरेटर सरणी फ़ील्ड पहले आपके प्रारंभिक एकत्रीकरण पाइपलाइन चरण के रूप में। यह ratings
का पुनर्निर्माण करेगा प्रत्येक तत्व के लिए एक दस्तावेज़ को आउटपुट करने के लिए इनपुट दस्तावेज़ों से सरणी फ़ील्ड। प्रत्येक आउटपुट दस्तावेज़ सरणी को एक तत्व मान से बदल देता है।
दूसरा पाइपलाइन चरण $group
. होगा ऑपरेटर जो इनपुट दस्तावेज़ों को _id
. द्वारा समूहित करता है और title
कुंजी पहचानकर्ता अभिव्यक्ति और वांछित $avg
. लागू करता है औसत की गणना करने वाले प्रत्येक समूह के लिए संचायक व्यंजक। एक और संचायक ऑपरेटर है $push
जो उपरोक्त समूह में प्रत्येक दस्तावेज़ में अभिव्यक्ति लागू करने के परिणामस्वरूप सभी मानों की एक सरणी लौटाकर मूल रेटिंग सरणी फ़ील्ड को संरक्षित करता है।
अंतिम पाइपलाइन चरण है $project
ऑपरेटर जो तब स्ट्रीम में प्रत्येक दस्तावेज़ को नया आकार देता है, जैसे कि नया फ़ील्ड ratings_average
जोड़कर ।
इसलिए, उदाहरण के लिए, यदि आपके संग्रह में एक नमूना दस्तावेज़ है (जैसा कि ऊपर और नीचे से):
db.collection.insert({
"title": "The Hobbit",
"ratings": [
{
"title": "best book ever",
"rating": 5
},
{
"title": "good book",
"rating": 3.5
}
]
})
रेटिंग सरणी औसत की गणना करने के लिए और किसी अन्य फ़ील्ड में मान का अनुमान लगाने के लिए ratings_average
, फिर आप निम्नलिखित एकत्रीकरण पाइपलाइन लागू कर सकते हैं:
db.collection.aggregate([
{
"$unwind": "$ratings"
},
{
"$group": {
"_id": {
"_id": "$_id",
"title": "$title"
},
"ratings":{
"$push": "$ratings"
},
"ratings_average": {
"$avg": "$ratings.rating"
}
}
},
{
"$project": {
"_id": 0,
"title": "$_id.title",
"ratings_average": 1,
"ratings": 1
}
}
])
परिणाम :
/* 1 */
{
"result" : [
{
"ratings" : [
{
"title" : "best book ever",
"rating" : 5
},
{
"title" : "good book",
"rating" : 3.5
}
],
"ratings_average" : 4.25,
"title" : "The Hobbit"
}
],
"ok" : 1
}