sql >> Base de Datos >  >> NoSQL >> MongoDB

obtenga todos los documentos que tengan el valor máximo usando la agregación en mongodb

Si desea conservar la información del documento, básicamente necesita $push en una matriz. Pero, por supuesto, tener su $max valores, debe filtrar el contenido de la matriz solo para los elementos que coincidan:

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]
            ]
        }
    }}
])

Así que almacena todo en una matriz y luego prueba cada miembro de la matriz para ver si su valor coincide con el que se registró como máximo, descartando los que no.

Yo mantendría el _id valores en los documentos de matriz, ya que eso es lo que los hace "únicos" y no se verán afectados negativamente por $setDifference al filtrar valores. Pero, por supuesto, si "nombre" siempre es único, entonces no será necesario.

También puede devolver los campos que desee desde $map , pero solo devuelvo el documento completo, por ejemplo.

Tenga en cuenta que esto tiene la limitación de no exceder el límite de tamaño de BSON de 16 MB, por lo que está bien para muestras de datos pequeños, pero cualquier cosa que produzca una lista potencialmente grande (ya que no puede prefiltrar el contenido de la matriz) sería mejor procesada con un consulta separada para encontrar los valores "máximos" y otra para obtener los documentos coincidentes.