sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB:Räknar hur många av varje distinkta värden det finns?

Du var väldigt nära, men naturligtvis $eq returnerar bara en true/false värde, så för att göra det numeriska behöver du $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 ]
           }
       }
  }}
])

Som en "ternär" operator $cond tar ett logiskt villkor som det första argumentet (om) och returnerar sedan det andra argumentet där utvärderingen är true (då) eller det tredje argumentet där false (annan). Detta gör true/false återgår till 1 och 0 att mata till $sum respektive.

Observera också att "case" är känsligt för $eq . Om du har olika skiftlägen vill du förmodligen ha $toLower i uttrycken:

               "$cond": [ { "$eq": [ { "$toLower": "$rating" },  "bad" ] }, 1, 0 ]

På en något annorlunda notering är följande aggregering vanligtvis mer flexibel för olika möjliga värden och kör ringar runt de villkorade summorna när det gäller prestanda:

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

Det skulle istället ge utdata så här:

{
    "_id": "item_1"
    "results":[
        { "rating": "good", "count": 12 },
        { "rating": "neutral", "count": 10 }
        { "rating": "bad", "count": 67 }
    ]
}

Det är samma information, men du behövde inte uttryckligen matcha värdena och det körs mycket snabbare på detta sätt.




  1. Vänta på återuppringning av asynkronfunktion i den senaste stream.on('data')-händelsen

  2. Importera data till MongoDB från JSON-fil med Java

  3. Vad är $unwind-operatören i MongoDB?

  4. Stubbar Redis-interaktioner i javascript med Sinon