Mit dem Aggregations-Framework weicht das Ergebnis geringfügig von Ihrer "gewünschten" Ausgabe ab, da Sie anstelle von Hash-Schlüsseln ein Array von Objekten mit der _id
erhalten Schlüssel mit einem Wert, der Ihre Gruppierung nach Feld darstellt. Zum Beispiel statt
{
"28-10-2016":{
"success_count": 10,
"failure_count": 10
},
"29-10-2016": {
"success_count": 10,
"failure_count": 10
}
}
Sie hätten eine bessere Struktur wie
[
{
"_id": "28-10-2016",
"success_count": 10,
"failure_count": 10
},
"_id": "29-10-2016",
"success_count": 10,
"failure_count": 10
}
]
Um das obige Ergebnis zu erzielen, wäre die Verwendung von $sum
Akkumulator-Operator. Der $cond
-Operator wertet eine logische Bedingung basierend auf ihrem ersten Argument (wenn) aus und gibt dann das zweite Argument zurück, wenn die Auswertung wahr ist (dann), oder das dritte Argument, wenn falsch (sonst). Dadurch wird die Wahr/Falsch-Logik in numerische Werte von 1 und 0 umgewandelt, die in $sum
bzw.:
"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
}
Als resultierende Pipeline muss man die Aggregationsoperation ausführen, die den $dateToString
Operator in der _id
Schlüsselausdruck für den $gruppe
Leitung:
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);
})
Es gibt jedoch einen flexibleren und leistungsfähigeren Ansatz, der viel schneller ausgeführt wird als der oben genannte, bei dem die effizienteste Datenstruktur für Ihr Aggregationsergebnis beispielsweise dem Schema folgt:
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 }
]
}
]
Erwägen Sie dann, eine alternative Pipeline wie folgt auszuführen
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);
})