MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongo Aggregation : $group et $project array à l'objet pour les décomptes

Avec MongoDb 3.4 et versions ultérieures, vous pouvez tirer parti de l'utilisation de $arrayToObject opérateur pour obtenir le résultat souhaité. Vous auriez besoin d'exécuter le pipeline agrégé suivant :

db.collection.aggregate([
    { "$group": {
        "_id": {  
            "date": "$install_date",  
            "platform": { "$toLower": "$platform" }
        },
        "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.date",
        "counts": {
            "$push": {
                "k": "$_id.platform",
                "v": "$count"
            }
        }
    } },
    {  "$addFields": {
        "install_date": "$_id", 
        "platform": { "$arrayToObject": "$counts" }
    }  },
    { "$project": { "counts": 0, "_id": 0 } } 
])

Pour les anciennes versions, profitez du $cond opérateur dans le $group étape de pipeline pour évaluer les décomptes en fonction de la valeur du champ de plate-forme, quelque chose comme ce qui suit :

db.collection.aggregate([    
    { "$group": { 
        "_id": "$install_date",             
        "android_count": {
            "$sum": {
                "$cond": [ { "$eq": [ "$platform", "android" ] }, 1, 0 ]
            }
        },
        "ios_count": {
            "$sum": {
                "$cond": [ { "$eq": [ "$platform", "ios" ] }, 1, 0 ]
            }
        },
        "facebook_count": {
            "$sum": {
                "$cond": [ { "$eq": [ "$platform", "facebook" ] }, 1, 0 ]
            }
        },
        "kindle_count": {
            "$sum": {
                "$cond": [ { "$eq": [ "$platform", "kindle" ] }, 1, 0 ]
            }
        } 
    } },
    { "$project": {
        "_id": 0, "install_date": "$_id",            
        "platform": {
            "android": "$android_count",
            "ios": "$ios_count",
            "facebook": "$facebook_count",
            "kindle": "$kindle_count"
        }
    } }
])

Dans ce qui précède, $cond prend une condition logique comme premier argument (if) puis renvoie le deuxième argument où l'évaluation est vraie (then) ou le troisième argument où false (else). Cela fait des retours vrai/faux en 1 et 0 pour alimenter $sum respectivement.

Ainsi, par exemple, si { "$eq": [ "$platform", "facebook" ] }, est vrai alors l'expression sera évaluée à { $sum: 1 } sinon ce sera { $sum: 0 }