Byli jste si velmi blízcí, ale samozřejmě $eq
pouze vrátí true/false
hodnotu, takže k vytvoření této číselné hodnoty potřebujete $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 ]
}
}
}}
])
Jako "ternární" operátor $cond
vezme logickou podmínku jako svůj první argument (if) a poté vrátí druhý argument, kde je vyhodnocení true
(pak) nebo třetí argument kde false
(jiný). Tím je true/false
vrátí do 1
a 0
na zdroj $sum
respektive.
Také si všimněte, že "case" je citlivé pro $eq
. Pokud máte různá malá a velká písmena, pravděpodobně budete chtít $toLower
ve výrazech:
"$cond": [ { "$eq": [ { "$toLower": "$rating" }, "bad" ] }, 1, 0 ]
Trochu jinak, následující agregace je obvykle flexibilnější pro různé možné hodnoty a běží kolem podmíněných součtů z hlediska výkonu:
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"
}
}
}}
])
To by místo toho poskytlo výstup takto:
{
"_id": "item_1"
"results":[
{ "rating": "good", "count": 12 },
{ "rating": "neutral", "count": 10 }
{ "rating": "bad", "count": 67 }
]
}
Jsou to všechny stejné informace, ale nemuseli jste explicitně shodovat hodnoty a tímto způsobem se to spouští mnohem rychleji.