假设有以下子文档:
{
"id":1,
"url":"mysite.com",
"views":
[
{"ip":"1.1.1.1","date":"01-01-2015"},
{"ip":"2.2.2.2","date":"01-01-2015"},
{"ip":"1.1.1.1","date":"01-01-2015"},
{"ip":"1.1.1.1","date":"01-01-2015"}
]
}
我想算一下:
"ip"
值"views"
如果可能在同一查询中,以实现以下结果:
[
{
"_id":"2.2.2.2",
"count":1
},
{
"_id":"1.1.1.1",
"count":3
},
{
"_id":"total",
"count":4
}
]
使用 MongoDB聚合框架,我已设法通过以下方式实现 1 点:
db.collection.aggregate([
{
"$unwind": "$views"
},
{
"$group": {
"_id": "$views.ip",
"count": {
"$sum": 1
}
}
}
])
返回:
[
{
"_id":"2.2.2.2",
"count":1
},
{
"_id":"1.1.1.1",
"count":3
}
]
我希望在数组中返回额外的doc,即:
{
"_id":"total",
"count":4
}
实现我上面暴露的内容,但我被困在那里并且无法这样做。
答案 0 :(得分:1)
在相同的聚合管道中不可能原则上管道在处理文件时对文件进行处理,即管道阶段不需要为每个输入文档生成一个输出文档;例如,某些阶段可以生成新文档或过滤掉文档。在上面的方案中,添加另一个 $group
步骤以获取分组的IP计数+总计数将产生与您所追求的不同的结果,即
db.collection.aggregate([
{
"$unwind": "$views"
},
{
"$group": {
"_id": "$views.ip",
"count": {
"$sum": 1
}
}
},
{
"$group": {
"_id": null,
"total": {
"$sum": "$count"
}
}
}
])
您将只获得总数,因为 $group
会消耗所有输入文档(包含分组IP计数的文档),并为每个不同的组输出一个文档。额外的组步骤将对上一个流中的所有文档进行分组。
但是,您可以获得总计数,但作为最终结果中每个分组文档中的额外字段。以下使用初始$project
管道阶段通过 $size
运算符获取总计数的示例可以实现此目的:
db.collection.aggregate([
{
"$project": {
"views": 1,
"views_size": { "$size": "$views" }
}
}
{
"$unwind": "$views"
},
{
"$group": {
"_id": "$views.ip",
"count": {
"$sum": 1
},
"total": { "$first": "$views_size" }
}
}
])
示例输出
[
{
"_id": "2.2.2.2",
"count": 1,
"total": 4
},
{
"_id": "1.1.1.1",
"count": 3,
"total": 4
}
]