Du var meget tæt på, men selvfølgelig $eq
returnerer bare en true/false
værdi, så for at gøre det numeriske skal du bruge $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 ]
}
}
}}
])
Som en "ternær" operator $cond
tager en logisk betingelse som det første argument (hvis) og returnerer derefter det andet argument, hvor evalueringen er true
(derefter) eller det tredje argument hvor false
(andet). Dette gør true/false
vender tilbage til 1
og 0
at feed til $sum
hhv.
Bemærk også, at "case" er følsom for $eq
. Hvis du har forskellige store og små bogstaver, vil du sandsynligvis have $toLower
i udtrykkene:
"$cond": [ { "$eq": [ { "$toLower": "$rating" }, "bad" ] }, 1, 0 ]
Med en lidt anden note er følgende aggregering normalt mere fleksibel til forskellige mulige værdier og kører ringe rundt om de betingede summer med hensyn til ydeevne:
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"
}
}
}}
])
Det ville i stedet give output som dette:
{
"_id": "item_1"
"results":[
{ "rating": "good", "count": 12 },
{ "rating": "neutral", "count": 10 }
{ "rating": "bad", "count": 67 }
]
}
Det er alle de samme oplysninger, men du behøvede ikke eksplicit at matche værdierne, og det udføres meget hurtigere på denne måde.