Anda sangat dekat, tapi tentu saja $eq
baru saja mengembalikan true/false
nilai, jadi untuk membuat numerik itu Anda perlu $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 ]
}
}
}}
])
Sebagai operator "ternary" $cond
mengambil kondisi logis sebagai argumen pertama (jika) dan kemudian mengembalikan argumen kedua di mana evaluasinya true
(kemudian) atau argumen ketiga di mana false
(lain). Ini membuat true/false
kembali ke 1
dan 0
untuk memberi makan ke $sum
masing-masing.
Perhatikan juga bahwa "huruf besar" sensitif untuk $eq
. Jika Anda memiliki varing case maka Anda mungkin ingin $toLower
dalam ekspresi:
"$cond": [ { "$eq": [ { "$toLower": "$rating" }, "bad" ] }, 1, 0 ]
Pada catatan yang sedikit berbeda, agregasi berikut biasanya lebih fleksibel untuk kemungkinan nilai yang berbeda dan menjalankan cincin di sekitar jumlah bersyarat dalam hal kinerja:
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"
}
}
}}
])
Itu malah akan memberikan output seperti ini:
{
"_id": "item_1"
"results":[
{ "rating": "good", "count": 12 },
{ "rating": "neutral", "count": 10 }
{ "rating": "bad", "count": 67 }
]
}
Ini semua informasi yang sama, tetapi Anda tidak harus secara eksplisit mencocokkan nilainya dan itu akan dieksekusi lebih cepat dengan cara ini.