Met het aggregatieraamwerk zal het resultaat enigszins verschillen van uw "gewenste" uitvoer, omdat u in plaats van hash-sleutels een array van objecten krijgt met de _id
sleutel met een waarde die u groepeert op veld. Bijvoorbeeld, in plaats van
{
"28-10-2016":{
"success_count": 10,
"failure_count": 10
},
"29-10-2016": {
"success_count": 10,
"failure_count": 10
}
}
je zou een betere structuur hebben zoals
[
{
"_id": "28-10-2016",
"success_count": 10,
"failure_count": 10
},
"_id": "29-10-2016",
"success_count": 10,
"failure_count": 10
}
]
Om het bovenstaande resultaat te bereiken, moet u de $cond
operator in de $sum
bediener van de accumulator. De $cond
operator evalueert een logische voorwaarde op basis van het eerste argument (if) en retourneert vervolgens het tweede argument waarbij de evaluatie waar is (then) of het derde argument waar onwaar (anders). Dit converteert de true/false-logica naar 1 en 0 numerieke waarden die worden ingevoerd in $sum
respectievelijk:
"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
}
Als resulterende pijplijn moet men de aggregatiebewerking uitvoeren die de $dateToString
operator in de _id
sleutelexpressie voor de $group
pijplijn:
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);
})
Er is echter een flexibelere en beter presterende aanpak die veel sneller wordt uitgevoerd dan de bovenstaande, waarbij de meest efficiënte gegevensstructuur voor uw aggregatieresultaat bijvoorbeeld het schema volgt:
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 }
]
}
]
Overweeg dan om als volgt een alternatieve pijplijn te gebruiken
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);
})