Com a estrutura de agregação, o resultado será um pouco diferente da sua saída "desejada", pois em vez de ter chaves de hash, você obtém uma matriz de objetos com o
_id
chave com um valor que representa seu grupo por campo. Por exemplo, em vez de {
"28-10-2016":{
"success_count": 10,
"failure_count": 10
},
"29-10-2016": {
"success_count": 10,
"failure_count": 10
}
}
você teria uma estrutura melhor como
[
{
"_id": "28-10-2016",
"success_count": 10,
"failure_count": 10
},
"_id": "29-10-2016",
"success_count": 10,
"failure_count": 10
}
]
A obtenção do resultado acima exigiria o uso do
$cond
operador no $sum
operador de acumulador. O $cond
O operador avaliará uma condição lógica com base em seu primeiro argumento (if) e, em seguida, retornará o segundo argumento onde a avaliação for verdadeira (então) ou o terceiro argumento onde for falso (else). Isso converte a lógica verdadeira/falsa em valores numéricos 1 e 0 que alimentam $sum
respectivamente:"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
}
Como um pipeline resultante, é necessário executar a operação de agregação que usa o
$dateToString
operador no _id
expressão-chave para o $grupo
encanamento: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);
})
No entanto, existe uma abordagem mais flexível e de melhor desempenho que executa muito mais rápido do que a acima, onde a estrutura de dados mais eficiente para o resultado da agregação segue o esquema, por exemplo:
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 }
]
}
]
Em seguida, considere executar um pipeline alternativo da seguinte maneira
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);
})