MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

obtenha todos os documentos com valor máximo usando agregação no mongodb


Se você deseja manter as informações do documento, basicamente precisa $push -lo em uma matriz. Mas, claro, ter seu $max valores, você precisa filtrar o conteúdo da matriz apenas para os elementos que correspondem:
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]
            ]
        }
    }}
])

Então você armazena tudo em um array e então testa cada membro do array para ver se seu valor corresponde ao que foi registrado como o máximo, descartando qualquer um que não corresponda.

Eu manteria o _id valores nos documentos da matriz, pois é isso que os torna "únicos" e não serão afetados negativamente por $setDifference ao filtrar os valores. Mas é claro que se "nome" for sempre exclusivo, não será necessário.

Você também pode retornar os campos que desejar de $map , mas estou apenas retornando o documento inteiro por exemplo.

Tenha em mente que isso tem a limitação de não exceder o limite de tamanho BSON de 16 MB, então é bom para pequenas amostras de dados, mas qualquer coisa que produza uma lista potencialmente grande (já que você não pode pré-filtrar o conteúdo da matriz) seria melhor processado com um consulta separada para encontrar os valores "max" e outra para buscar os documentos correspondentes.