Bạn đã ở rất gần, nhưng tất nhiên là $eq
chỉ trả về true/false
giá trị, vì vậy để tạo thành số đó, bạn cần $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 ]
}
}
}}
])
Là toán tử "bậc ba" $cond
nhận một điều kiện logic làm đối số đầu tiên (nếu) và sau đó trả về đối số thứ hai trong đó đánh giá là true
(then) hoặc đối số thứ ba trong đó false
(khác). Điều này làm cho true/false
trả về 1
và 0
để cấp cho $sum
tương ứng.
Cũng lưu ý rằng "chữ hoa chữ thường" là phân biệt đối với $eq
. Nếu bạn có trường hợp varing thì bạn có thể muốn $toLower
trong các biểu thức:
"$cond": [ { "$eq": [ { "$toLower": "$rating" }, "bad" ] }, 1, 0 ]
Có một lưu ý hơi khác, tập hợp sau thường linh hoạt hơn với các giá trị có thể khác nhau và chạy vòng quanh các tổng điều kiện về mặt hiệu suất:
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"
}
}
}}
])
Thay vào đó, điều đó sẽ cung cấp đầu ra như thế này:
{
"_id": "item_1"
"results":[
{ "rating": "good", "count": 12 },
{ "rating": "neutral", "count": 10 }
{ "rating": "bad", "count": 67 }
]
}
Đó là tất cả thông tin giống nhau, nhưng bạn không cần phải khớp các giá trị một cách rõ ràng và nó thực thi nhanh hơn nhiều theo cách này.