我有以下文件:
{
"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"}
]
}
如果我想计算多少独特的ips(groupBy),我怎么能用mongo做到这一点?
答案 0 :(得分:2)
使用 aggregation framework 获取所需结果。聚合管道将具有$unwind
操作作为第一步,其从输入文档解构views
数组字段以输出每个元素的文档。每个输出文档都使用元素值替换数组。然后,下一个管道阶段$group
按"views.ip"
字段对文档进行分组,计算每个组的count
字段,并为每个唯一状态输出文档。
新的per-ip文档有两个字段:_id
字段和count
字段。 _id
字段包含唯一IP地址的值;即按字段分组。 count
字段是计算字段,其中包含每个唯一IP的总ip计数。要计算该值,$group
使用$sum
运算符来计算IP地址的总数。所以你的最终聚合管道看起来像这样:
db.collection.aggregate([
{
"$unwind": "$views"
},
{
"$group": {
"_id": "$views.ip",
"count": {
"$sum": 1
}
}
}
])
<强>输出强>:
/* 1 */
{
"result" : [
{
"_id" : "2.2.2.2",
"count" : 1
},
{
"_id" : "1.1.1.1",
"count" : 3
}
],
"ok" : 1
}
- 更新 -
要获得所有唯一IP的总和,您需要另一个$group
管道阶段,这次_id为null,即您将前一个管道流中的所有文档分组为一个,然后使用相同的{ {3}}对该组进行操作以获得总计数。聚合管道最终看起来像这样:
db.collection.aggregate([
{
"$unwind": "$views"
},
{
"$group": {
"_id": "$views.ip",
"count": {
"$sum": 1
}
}
},
{
"$group": {
"_id": null,
"total": {
"$sum": "$count"
}
}
}
])
<强>输出强>:
/* 1 */
{
"result" : [
{
"_id" : null,
"total" : 4
}
],
"ok" : 1
}