आप बहुत करीब थे, लेकिन निश्चित रूप से $eq
बस एक true/false
लौटाता है मान, इसलिए उस संख्यात्मक को बनाने के लिए आपको $cond
. की आवश्यकता होगी :
db.collection(collectionName).aggregate([
{ "$group" : {
"_id": "$item",
"good_count": {
"$sum": {
"$cond": [ { "$eq": [ "$rating", "good" ] }, 1, 0]
}
},
"neutral_count":{
"$sum": {
"$cond": [ { "$eq": [ "$rating", "neutral" ] }, 1, 0 ]
}
},
"bad_count": {
"$sum": {
"$cond": [ { "$eq": [ "$rating", "bad" ] }, 1, 0 ]
}
}
}}
])
एक "टर्नरी" ऑपरेटर के रूप में $cond
तार्किक स्थिति लेता है क्योंकि यह पहला तर्क (यदि) है और फिर दूसरा तर्क देता है जहां मूल्यांकन true
है (तब) या तीसरा तर्क जहां false
(वरना)। यह true/false
बनाता है 1
. में वापस आ जाता है और 0
$sum
. को फीड करने के लिए क्रमशः।
यह भी ध्यान दें कि "केस" $eq
. के लिए संवेदनशील है . यदि आपके पास भिन्न मामला है तो आप संभवतः $toLower
. चाहते हैं भावों में:
"$cond": [ { "$eq": [ { "$toLower": "$rating" }, "bad" ] }, 1, 0 ]
थोड़ा अलग नोट पर, निम्नलिखित एकत्रीकरण आमतौर पर विभिन्न संभावित मूल्यों के लिए अधिक लचीला होता है और प्रदर्शन के संदर्भ में सशर्त रकम के आसपास रिंग चलाता है:
db.collection(collectionName).aggregate([
{ "$group": {
"_id": {
"item": "$item",
"rating": { "$toLower": "$rating" }
},
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id.item",
"results": {
"$push": {
"rating": "$_id.rating",
"count": "$count"
}
}
}}
])
इसके बजाय यह इस तरह से आउटपुट देगा:
{
"_id": "item_1"
"results":[
{ "rating": "good", "count": 12 },
{ "rating": "neutral", "count": 10 }
{ "rating": "bad", "count": 67 }
]
}
यह सभी समान जानकारी है, लेकिन आपको मूल्यों का स्पष्ट रूप से मिलान करने की आवश्यकता नहीं है और यह इस तरह से बहुत तेजी से निष्पादित होता है।