从单个MongoDB聚合中获取多个$ sum

时间:2014-04-09 19:26:53

标签: mongodb mongodb-query

我们有一个类似于此的模式(简化为相关部分):

{
    time: ISODate,
    data: {
        user: {
            username: String,
            ...
        },
        type: String,
        ...
    }
}

我需要聚合每个用户的数据并获取不同“类型”值的计数。所以假设以下数据:

[
    { time: ISODate(...), data: {user: {username: 'bob'}, type: 'value1'} },
    { time: ISODate(...), data: {user: {username: 'bob'}, type: 'value1'} },
    { time: ISODate(...), data: {user: {username: 'bob'}, type: 'value1'} },
    { time: ISODate(...), data: {user: {username: 'bob'}, type: 'value2'} },
    { time: ISODate(...), data: {user: {username: 'bob'}, type: 'value2'} },
    { time: ISODate(...), data: {user: {username: 'joe'}, type: 'value1'} },
    { time: ISODate(...), data: {user: {username: 'joe'}, type: 'value1'} }
]

我需要获得以下信息:

[
    { username: 'bob', value1: 3, value2: 2 },
    { username: 'joe', value1: 2, value2: 0 }
]

结果数据的实际结构并不像拥有正确的信息那么重要。如何编写聚合查询以获取此数据?

1 个答案:

答案 0 :(得分:3)

使用aggregate获取您要查找的数据的一种方法是在$push阶段使用$group运算符,如下所示:

db.collection.aggregate([
    {"$group":{
        _id:{username:"$data.user.username", 
        type:"$data.type"}, 
        count:{$sum:1}}
    }, 
    {"$group":{
        _id:"$_id.username", 
        values:{$push:{value:"$_id.type", count:"$count"}}}
    }
])

这是输出:

{
        "result" : [
                {
                        "_id" : "joe",
                        "values" : [
                                {
                                        "value" : "value1",
                                        "count" : 2
                                }
                        ]
                },
                {
                        "_id" : "bob",
                        "values" : [
                                {
                                        "value" : "value2",
                                        "count" : 2
                                },
                                {
                                        "value" : "value1",
                                        "count" : 3
                                }
                        ]
                }
        ],
        "ok" : 1
}