MongoDB Count和groupby子文档

时间:2015-05-10 18:03:03

标签: mongodb

我有以下文件:

{
    "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做到这一点?

1 个答案:

答案 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
}