MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Holen Sie sich alle Dokumente mit maximalem Wert mithilfe der Aggregation in Mongodb

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.