我有一个简单的聚合,只是在特定时间范围内按状态返回一个用户总和。
User.aggregate([
{
$match: {
"created" : {
$gt: startDate,
$lt: endDate
}
}
},
{
$group: {
"_id": "$status",
"count" : {
$sum: 1
}
}
}
])
我想做的是显示日期范围内每天的数据,即使没有数据。
因此,例如,结果可能会像这样结束:
[{
'_id' : '01-15-2015',
status_counts: {
'active': 15,
'inactive': 25,
'removed': 2
}
},
{
'_id' : '01-16-2015',
status_counts: {
'active': 0,
'inactive': 0,
'removed': 0
}
},
{
'_id' : '01-17-2015',
status_counts: {
'active': 25,
'inactive': 5,
'removed': 1
}
}]
我有什么想法可以做到这一点?基本上汇总所有状态并按天分组,但如果没有数据,则包括默认数据归零?
示例数据:
[{
"_id" : ObjectId("55413bc29d41675785bf7ed2"),
"status" : "active",
"created" : ISODate("2015-10-11T17:25:46.843Z")
},
{
"_id" : ObjectId("55413bc29d41675785bf7ed2"),
"status" : "inactive",
"created" : ISODate("2015-10-12T17:25:46.843Z")
},
{
"_id" : ObjectId("55413bc29d41675785bf7ed2"),
"status" : "removed",
"created" : ISODate("2015-10-12T17:25:46.843Z")
},
{
"_id" : ObjectId("55413bc29d41675785bf7ed2"),
"status" : "active",
"created" : ISODate("2015-10-14T17:25:46.843Z")
},
{
"_id" : ObjectId("55413bc29d41675785bf7ed2"),
"status" : "active",
"created" : ISODate("2015-10-14T17:25:46.843Z")
},
{
"_id" : ObjectId("55413bc29d41675785bf7ed2"),
"status" : "active",
"created" : ISODate("2015-10-17T17:25:46.843Z")
}]
示例结果:
[{
"_id":"10-11-2015",
"status_counts": {
"active":1,
"inactive":0,
"removed":0
}
},
{
"_id":"10-12-2015",
"status_counts": {
"active":0,
"inactive":1,
"removed":1
}
},
{
"_id":"10-13-2015",
"status_counts": {
"active":0,
"inactive":0,
"removed":0
}
},
{
"_id":"10-14-2015",
"status_counts": {
"active":2,
"inactive":0,
"removed":0
}
},
{
"_id":"10-15-2015",
"status_counts": {
"active":0,
"inactive":0,
"removed":0
}
},
{
"_id":"10-16-2015",
"status_counts": {
"active":0,
"inactive":0,
"removed":0
}
},
{
"_id":"10-17-2015",
"status_counts": {
"active":1,
"inactive":0,
"removed":0
}
}]
答案 0 :(得分:1)
使用以下管道,其中 $project
阶段的管道使用 {{创建具有仅由月 - 日 - 年组成的新属性的文档3}} 和 date aggregation operators string operators , $concat
运营商字符串操作。然后,您可以使用前面 $subtr
管道步骤中的新属性作为组密钥,并使用 $group
运算符获取相应的状态计数评估状态类型并将值分配给 $cond
。结束 $sum
管道阶段然后重新整形最终文档,以在子文档中提供所需的字段:
User.aggregate([
{
"$match": {
"created": { "$gt": startDate, "$lt": endDate }
}
},
{
"$project": {
"_id": 0, "status": 1,
"dayPart": {
"$concat" : [
{
"$substr": [ {"$month" : "$created"}, 0, 2 ]
}, "-",
{
"$substr": [ {"$dayOfMonth" : "$created"}, 0, 2 ]
}, "-",
{
"$substr": [ {"$year" : "$created"}, 0, 4 ]
}
]
}
}
},
{
"$group": {
"_id": "$dayPart",
"active_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "active" ] }, 1, 0 ]
}
},
"inactive_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "inactive" ] }, 1, 0 ]
}
},
"removed_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "removed" ] }, 1, 0 ]
}
}
}
},
{
"$project": {
"status_counts": {
"active": "$active_count",
"inactive": "$inactive_count",
"removed": "$removed_count"
}
}
}
])