Abh*_*rma 0 database mongoose mongodb mongodb-query aggregation-framework
馆藏结构
Order = new Schema
index: { type: Number, unique: true }
number: Date
status: { type: String, enum: ['success', 'failure'] }
created_at: { type: Date, default: Date.now }
updated_at: { type: Date, default: Date.now }
Run Code Online (Sandbox Code Playgroud)
我需要有关查询的帮助,该查询返回一组对象,这些对象的数据为按日期分组的成功计数和失败计数。前任-
orders = {
28-10-2016:{
success_count: 10,
failure_count: 10
},
29-10-2016: {
success_count: 10,
failure_count: 10
}
}
Run Code Online (Sandbox Code Playgroud)
使用聚合框架,结果将与您的“期望”输出略有不同,因为您将获得一个对象数组,其_id键的值代表您按字段分组。例如,代替
{
"28-10-2016":{
"success_count": 10,
"failure_count": 10
},
"29-10-2016": {
"success_count": 10,
"failure_count": 10
}
}
Run Code Online (Sandbox Code Playgroud)
你会有一个更好的结构,比如
[
{
"_id": "28-10-2016",
"success_count": 10,
"failure_count": 10
},
"_id": "29-10-2016",
"success_count": 10,
"failure_count": 10
}
]
Run Code Online (Sandbox Code Playgroud)
实现上述结果需要$cond在$sum累加器运算符中使用运算符。该$cond运营商将评估基于其第一个参数(如果)的逻辑条件,然后返回,其中评价是真实的(当时)的第二个参数或第三个参数,其中假(否则)。这将真/假逻辑转换为 1 和 0 数值,$sum分别输入:
"success_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
}
}
Run Code Online (Sandbox Code Playgroud)
作为结果管道,需要运行聚合操作,该$dateToString操作在管道的_id键表达式中使用运算符$group:
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);
})
Run Code Online (Sandbox Code Playgroud)
但是,有一种更灵活、性能更好的方法,它的执行速度比上述方法快得多,聚合结果的最有效数据结构遵循以下模式,例如:
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 }
]
}
]
Run Code Online (Sandbox Code Playgroud)
然后考虑按如下方式运行替代管道
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);
})
Run Code Online (Sandbox Code Playgroud)