Ano, je to trochu těžší vzhledem k tomu, že existuje více polí, a pokud zkusíte obě současně, skončíte s „karteziánskou podmínkou“, kdy jedno pole násobí obsah druhého.
Zkombinujte proto obsah pole na začátku, což pravděpodobně naznačuje, jak byste měli data ukládat:
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) {
}
)
Takže přes první $project
uspořádat $map
operátory přidávají hodnotu "type" ke každé položce každého pole. Ne že by na tom opravdu záleželo, protože všechny položky by stejně měly zpracovávat „jedinečně“, $setUnion
operátor „contatenated“ každé pole do singulárního pole.
Jak již bylo zmíněno dříve, pravděpodobně byste měli tímto způsobem ukládat na prvním místě.
Poté zpracujte $unwind
následuje $group
, kde se každé „pro“ a „proti“ vyhodnotí pomocí $cond
to odpovídá "type", buď vrací 1
nebo 0
kde je shoda true/false
na $sum
agregační akumulátor.
To vám dává "logickou shodu" pro počítání každého příslušného "typu" v rámci operace agregace podle zadaných seskupovacích klíčů.