Niet direct zichtbaar maar mogelijk. Wat u hier moet doen, is uw document op het hoogste niveau combineren met de reeks opmerkingen zonder het te dupliceren. Hier is een benadering om de inhoud eerst als twee arrays samen te voegen tot een enkelvoudige array en vervolgens $unwind
om de inhoud te groeperen:
db.collection.aggregate([
{ "$group": {
"_id": "$_id",
"author": {
"$addToSet": {
"id": "$_id",
"author": "$author",
"votes": "$votes"
}
},
"comments": { "$first": "$comments" }
}},
{ "$project": {
"combined": { "$setUnion": [ "$author", "$comments" ] }
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
Wat de output geeft:
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }
Zelfs als het overslaan van de eerste $group
stage en een gecombineerde array op een andere manier maken:
db.collection.aggregate([
{ "$project": {
"combined": {
"$setUnion": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "el",
"in": {
"author": "$author",
"votes": "$votes"
}
}},
"$comments"
]
}
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
Die gebruiken operators zoals $setUnion
en zelfs $map
die werden geïntroduceerd vanaf MongoDB 2.6. Dit maakt het eenvoudiger, maar het kan nog steeds worden gedaan in eerdere versies zonder deze operators, volgens vrijwel dezelfde principes:
db.collection.aggregate([
{ "$project": {
"author": 1,
"votes": 1,
"comments": 1,
"type": { "$const": ["A","B"] }
}},
{ "$unwind": "$type" },
{ "$unwind": "$comments" },
{ "$group": {
"_id": {
"$cond": [
{ "$eq": [ "$type", "A" ] },
{
"id": "$_id",
"author": "$author",
"votes": "$votes"
},
"$comments"
]
}
}},
{ "$group": {
"_id": "$_id.author",
"votes": { "$sum": "$_id.votes" }
}},
{ "$sort": { "votes": -1 } }
])
De $const
is niet gedocumenteerd maar aanwezig in alle versies van MongoDB waar het aggregatieraamwerk aanwezig is (vanaf 2.2). MongoDB 2.6 introduceerde $literal
die in wezen naar dezelfde onderliggende code linkt. Het is hier in twee gevallen gebruikt om ofwel een sjabloonelement voor een array te leveren, of als introductie van een array om af te wikkelen om een "binaire keuze" tussen twee acties te bieden.