Бяхте много близки, но разбира се $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
приема логическо условие като първи аргумент (if) и след това връща втория аргумент, където оценката е true
(тогава) или третият аргумент, където false
(друго). Това прави true/false
се връща в 1
и 0
за подаване към $sum
съответно.
Също така имайте предвид, че "case" е чувствителен за $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 }
]
}
Всичко е една и съща информация, но не е трябвало изрично да съпоставяте стойностите и тя се изпълнява много по-бързо по този начин.