Als u documentinformatie wilt behouden, moet u in principe $push
het in een array. Maar dan natuurlijk je $max
waarden, moet u de inhoud van de array filteren op alleen de elementen die overeenkomen:
db.coll.aggregate([
{ "$group":{
"_id": "$country",
"maxQuantity": { "$max": "$quantity" },
"docs": { "$push": {
"_id": "$_id",
"name": "$name",
"quantity": "$quantity"
}}
}},
{ "$project": {
"maxQuantity": 1,
"docs": {
"$setDifference": [
{ "$map": {
"input": "$docs",
"as": "doc",
"in": {
"$cond": [
{ "$eq": [ "$maxQuantity", "$$doc.quantity" ] },
"$$doc",
false
]
}
}},
[false]
]
}
}}
])
Dus je slaat alles op in een array en test vervolgens elk arraylid om te zien of de waarde overeenkomt met de waarde die als maximum is vastgelegd, waarbij je alle leden weggooit die dat niet doen.
Ik zou de _id
. behouden waarden in de array-documenten, want dat maakt ze "uniek" en wordt niet nadelig beïnvloed door $setDifference
bij het uitfilteren van waarden. Maar als "naam" altijd uniek is, is het natuurlijk niet vereist.
Je kunt ook gewoon alle velden retourneren die je wilt van $map
, maar ik stuur bijvoorbeeld gewoon het hele document terug.
Houd er rekening mee dat dit de beperking heeft dat de BSON-limiet van 16 MB niet wordt overschreden, dus het is oké voor kleine gegevensmonsters, maar alles wat een potentieel grote lijst oplevert (omdat u array-inhoud niet vooraf kunt filteren) kan beter worden verwerkt met een aparte zoekopdracht om de "max" waarden te vinden, en een andere om de overeenkomende documenten op te halen.