Med aggregeringsramverket kommer resultatet att skilja sig något från din "önskade" utdata eftersom du istället för att ha hash-nycklar får en array av objekt med _id
nyckel som har ett värde som representerar dig grupperad efter fält. Till exempel istället för
{
"28-10-2016":{
"success_count": 10,
"failure_count": 10
},
"29-10-2016": {
"success_count": 10,
"failure_count": 10
}
}
du skulle ha en bättre struktur som
[
{
"_id": "28-10-2016",
"success_count": 10,
"failure_count": 10
},
"_id": "29-10-2016",
"success_count": 10,
"failure_count": 10
}
]
För att uppnå ovanstående resultat måste du använda $cond
operatorn i $sum
ackumulatoroperatör. $cond
operatorn kommer att utvärdera ett logiskt villkor baserat på dess första argument (if) och returnerar sedan det andra argumentet där utvärderingen är sant (då) eller det tredje argumentet där falskt (annat). Detta konverterar sann/falsk logik till 1 och 0 numeriska värden som matas in i $summa
respektive:
"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
}
Som en resulterande pipeline måste man köra aggregeringsoperationen som använder $dateToString
operatorn i _id
nyckeluttryck för $grupp
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);
})
Det finns dock ett mer flexibelt och bättre presterande tillvägagångssätt som exekverar mycket snabbare än ovanstående, där den mest effektiva datastrukturen för ditt aggregeringsresultat följer schemat till exempel:
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 }
]
}
]
Överväg sedan att köra en alternativ pipeline enligt följande
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);
})