Om du vill behålla dokumentinformation måste du i princip $push
det till en array. Men självklart, sedan ha din $max
värden måste du filtrera innehållet i arrayen för bara de element som matchar:
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]
]
}
}}
])
Så du lagrar allt i en array och testar sedan varje arraymedlem för att se om dess värde matchar det som registrerades som maximalt, och kasserar alla som inte gör det.
Jag skulle behålla _id
värden i arraydokumenten eftersom det är det som gör dem "unika" och inte kommer att påverkas negativt av $setDifference
när du filtrerar bort värden. Men om "namn" alltid är unikt kommer det naturligtvis inte att behövas.
Du kan också bara returnera vilka fält du vill från $map
, men jag lämnar bara tillbaka hela dokumentet till exempel.
Tänk på att detta har begränsningen att inte överskrida BSON-storleksgränsen på 16 MB, så det är okej för små dataprover, men allt som producerar en potentiellt stor lista (eftersom du inte kan förfiltrera arrayinnehåll) skulle vara bättre att bearbeta med en separat fråga för att hitta "max"-värdena och en annan för att hämta matchande dokument.