Wenn Sie Dokumentinformationen behalten möchten, müssen Sie grundsätzlich $push
es in ein Array. Aber natürlich, dann haben Sie Ihren $max
Werten müssen Sie den Inhalt des Arrays nur nach den übereinstimmenden Elementen filtern:
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]
]
}
}}
])
Sie speichern also alles in einem Array und testen dann jedes Array-Mitglied, um zu sehen, ob sein Wert mit dem übereinstimmt, der als Maximum aufgezeichnet wurde, und verwerfen alle, die dies nicht tun.
Ich würde die _id
behalten Werte in den Array-Dokumenten, da sie dadurch "einzigartig" sind und nicht durch $setDifference
beim Herausfiltern von Werten. Aber natürlich, wenn "name" immer eindeutig ist, dann ist es nicht erforderlich.
Sie können auch einfach beliebige Felder aus $map
, aber ich gebe zum Beispiel nur das gesamte Dokument zurück.
Beachten Sie, dass dies die Beschränkung hat, die BSON-Größenbeschränkung von 16 MB nicht zu überschreiten, also für kleine Datenproben in Ordnung ist, aber alles, was eine potenziell große Liste erzeugt ( da Sie Array-Inhalte nicht vorfiltern können ), würde besser mit a verarbeitet werden separate Abfrage, um die "Max"-Werte zu finden, und eine weitere, um die passenden Dokumente abzurufen.