Du warst sehr nah dran, aber natürlich $eq
gibt nur ein true/false
zurück Wert, also um diese Zahl zu machen, brauchen Sie $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 ]
}
}
}}
])
Als "ternärer" Operator $cond
nimmt eine logische Bedingung als erstes Argument (if) und gibt dann das zweite Argument zurück, wobei die Auswertung true
ist (dann) oder das dritte Argument, wobei false
(anders). Dies macht true/false
kehrt in 1
zurück und 0
an $sum
zu füttern bzw..
Beachten Sie auch, dass "case" für $eq
empfindlich ist . Wenn Sie unterschiedliche Groß- und Kleinschreibung haben, möchten Sie wahrscheinlich $toLower
in den Ausdrücken:
"$cond": [ { "$eq": [ { "$toLower": "$rating" }, "bad" ] }, 1, 0 ]
Auf einer etwas anderen Anmerkung ist die folgende Aggregation normalerweise flexibler für verschiedene mögliche Werte und umgeht die bedingten Summen in Bezug auf die Leistung:
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"
}
}
}}
])
Das würde stattdessen eine Ausgabe wie diese geben:
{
"_id": "item_1"
"results":[
{ "rating": "good", "count": 12 },
{ "rating": "neutral", "count": 10 }
{ "rating": "bad", "count": 67 }
]
}
Es sind alle die gleichen Informationen, aber Sie mussten die Werte nicht explizit abgleichen und es wird auf diese Weise viel schneller ausgeführt.