Avec le framework d'agrégation, le résultat sera légèrement différent de votre sortie "souhaitée" car au lieu d'avoir des clés de hachage, vous obtenez un tableau d'objets avec le _id
clé ayant une valeur qui représente votre groupe par champ. Par exemple, au lieu de
{
"28-10-2016":{
"success_count": 10,
"failure_count": 10
},
"29-10-2016": {
"success_count": 10,
"failure_count": 10
}
}
vous auriez une meilleure structure comme
[
{
"_id": "28-10-2016",
"success_count": 10,
"failure_count": 10
},
"_id": "29-10-2016",
"success_count": 10,
"failure_count": 10
}
]
Pour obtenir le résultat ci-dessus, il faudrait utiliser le $cond
opérateur dans $sum
opérateur d'accumulateur. Le $cond
L'opérateur évaluera une condition logique en fonction de son premier argument (if), puis retournera le deuxième argument où l'évaluation est vraie (then) ou le troisième argument où false (else). Cela convertit la logique vrai/faux en valeurs numériques 1 et 0 qui alimentent $sum
respectivement :
"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
}
En tant que pipeline résultant, il faut exécuter l'opération d'agrégation qui utilise le $dateToString
opérateur dans le _id
expression clé pour $group
pipeline :
Orders.aggregate([
{
"$group": {
"_id": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$created_at"
}
},
"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
},
"failure_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "failure" ] }, 1, 0 ]
}
}
}
}
], function (err, orders){
if (err) throw err;
console.log(orders);
})
Cependant, il existe une approche plus flexible et plus performante qui s'exécute beaucoup plus rapidement que ci-dessus, où la structure de données la plus efficace pour votre résultat d'agrégation suit le schéma par exemple :
orders = [
{
"_id": "28-10-2016",
"counts": [
{ "status": "success", "count": 10 },
{ "status": "failure", "count": 10 }
]
},
{
"_id": "29-10-2016",
"counts": [
{ "status": "success", "count": 10 },
{ "status": "failure", "count": 10 }
]
}
]
Envisagez ensuite d'exécuter un pipeline alternatif comme suit
Orders.aggregate([
{
"$group": {
"_id": {
"date": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$created_at"
}
},
"status": { "$toLower": "$status" }
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.date",
"counts": {
"$push": {
"status": "$_id.status",
"count": "$count"
}
}
}
}
], function (err, orders){
if (err) throw err;
console.log(orders);
})