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

MongoDB:Contando quantos de cada valores distintos existem?


Você estava muito perto, mas é claro $eq apenas retorna um true/false valor, então para tornar esse numérico você precisa de $cond :
db.collection(collectionName).aggregate([
  { "$group" : {
       "_id": "$item",
       "good_count": { 
           "$sum": { 
               "$cond": [ { "$eq": [ "$rating",  "good" ] }, 1, 0] 
           }
       },
       "neutral_count":{
           "$sum": { 
               "$cond": [ { "$eq": [ "$rating", "neutral" ] }, 1, 0 ]
            }
       },
       "bad_count": { 
           "$sum": { 
               "$cond": [ { "$eq": [ "$rating",  "bad" ] }, 1, 0 ]
           }
       }
  }}
])

Como operador "ternário" $cond pega uma condição lógica como seu primeiro argumento (if) e então retorna o segundo argumento onde a avaliação é true (então) ou o terceiro argumento onde false (senão). Isso torna true/false retorna em 1 e 0 para alimentar $sum respectivamente.

Observe também que "case" é sensível para $eq . Se você tiver maiúsculas e minúsculas, provavelmente desejará $toLower nas expressões:
               "$cond": [ { "$eq": [ { "$toLower": "$rating" },  "bad" ] }, 1, 0 ]

Em uma nota um pouco diferente, a seguinte agregação geralmente é mais flexível para diferentes valores possíveis e executa anéis em torno das somas condicionais em termos de desempenho:
db.collection(collectionName).aggregate([
    { "$group": {
        "_id": { 
            "item": "$item",
            "rating": { "$toLower": "$rating" }
        },
        "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": "$_id.item",
        "results": {
            "$push": {
                "rating": "$_id.rating",
                "count": "$count"
            }
        }
    }}
])

Em vez disso, isso daria uma saída como esta:
{
    "_id": "item_1"
    "results":[
        { "rating": "good", "count": 12 },
        { "rating": "neutral", "count": 10 }
        { "rating": "bad", "count": 67 }
    ]
}

São todas as mesmas informações, mas você não precisou corresponder explicitamente aos valores e é executado muito mais rápido dessa maneira.