Có, điều này khó hơn một chút khi xét đến việc có nhiều mảng và nếu bạn thử cả hai cùng một lúc, bạn sẽ gặp phải "điều kiện cartesian" trong đó một mảng nhân với nội dung của mảng kia.
Do đó, chỉ cần kết hợp nội dung mảng ở phần đầu, điều này có thể cho biết bạn nên lưu trữ dữ liệu như thế nào ngay từ đầu:
Model.aggregate(
[
{ "$project": {
"company": 1,
"model": 1,
"data": {
"$setUnion": [
{ "$map": {
"input": "$pros",
"as": "pro",
"in": {
"type": { "$literal": "pro" },
"value": "$$pro"
}
}},
{ "$map": {
"input": "$cons",
"as": "con",
"in": {
"type": { "$literal": "con" },
"value": "$$con"
}
}}
]
}
}},
{ "$unwind": "$data" }
{ "$group": {
"_id": {
"company": "$company",
"model": "$model",
"tag": "$data.value"
},
"pros": {
"$sum": {
"$cond": [
{ "$eq": [ "$data.type", "pro" ] },
1,
0
]
}
},
"cons": {
"$sum": {
"$cond": [
{ "$eq": [ "$data.type", "con" ] },
1,
0
]
}
}
}
],
function(err,result) {
}
)
Vì vậy, thông qua $project
đầu tiên
giai đoạn $map
toán tử đang thêm giá trị "loại" vào từng mục của mỗi mảng. Ở đây không thực sự quan trọng vì tất cả các mục đều phải xử lý "duy nhất", $setUnion
toán tử "quy đổi" mỗi mảng thành một mảng số ít.
Như đã đề cập trước đó, có lẽ bạn nên lưu trữ theo cách này ngay từ đầu.
Sau đó, xử lý $unwind
theo sau là $group
, trong đó mỗi "ưu" và "nhược điểm" sau đó được đánh giá qua $cond
đối với nó phù hợp với "loại", trả về 1
hoặc 0
trong đó kết quả phù hợp tương ứng là true/false
tới $sum
bộ tích lũy tổng hợp.
Điều này cung cấp cho bạn một "đối sánh logic" để đếm từng "loại" tương ứng trong hoạt động tổng hợp theo các khóa nhóm được chỉ định.