Ya, ini sedikit lebih sulit mengingat ada banyak array, dan jika Anda mencoba keduanya secara bersamaan, Anda akan mendapatkan "kondisi kartesius" di mana satu array mengalikan konten yang lain.
Oleh karena itu, gabungkan saja konten array di awal, yang mungkin menunjukkan bagaimana Anda seharusnya menyimpan data sejak awal:
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) {
}
)
Jadi melalui $project
pertama
tahap $map
operator menambahkan nilai "tipe" ke setiap item dari setiap larik. Bukan berarti itu benar-benar penting di sini karena semua item harus memproses "unik", bagaimanapun, $setUnion
operator "mengkontaminasi" setiap larik menjadi larik tunggal.
Seperti yang disebutkan sebelumnya, Anda mungkin harus menyimpan dengan cara ini sejak awal.
Kemudian proses $unwind
diikuti oleh $group
, di mana setiap "pro" dan "kontra" kemudian dievaluasi melalui $cond
untuk itu cocok dengan "tipe", baik mengembalikan 1
atau 0
di mana kecocokan masing-masing adalah true/false
ke $sum
akumulator agregasi.
Ini memberi Anda "kecocokan logis" untuk menghitung masing-masing "jenis" dalam operasi agregasi sesuai dengan kunci pengelompokan yang ditentukan.