如何计算MongoDB中具有条件的唯一项的数量

时间:2014-02-28 12:15:24

标签: mongodb mongodb-query aggregation-framework

我的mongoDB中有这样的数据:

db.x.insert({"time" : ISODate("2014-02-29T00:00:00Z"), "user" : "3" });
db.x.insert({"time" : ISODate("2014-02-29T00:00:00Z"), "user" : "2" });
...

我有一个聚合函数来计算某些时间间隔内的活动,

db.x.aggregate([{
    "$group":{
     "_id":
         {"$cond":[
             {"$and":[
                 {"$gte": ["$time", ISODate("2014-02-15T00:00:00Z")]},
                 {"$lt" : ["$time", ISODate("2014-03-01T00:00:00Z")]}
             ]},
             "season1",
             {"$cond":[
                 {"$and":[
                      {"$gte": ["$time", ISODate("2014-03-01T00:00:00Z")]},
                      {"$lt" : ["$time", ISODate("2014-03-15T00:00:00Z")]}
                  ]},
                  "season2",
                  null
             ]}
        ]},
        "count": {"$sum": 1}
    }},
    {"$sort": { "_id": 1 }}
])

它可以正常使用这样的结果

{
    "result" : [
        {
            "_id" : "season1",
            "count" : 7
        },
        {
            "_id" : "season2",
            "count" : 7
        }
    ],
    "ok" : 1
}

但我真的被困在如何计算每个时间段内有多少独特用户? 有没有办法在没有为每个时间间隔调用mongo的情况下执行此操作?

1 个答案:

答案 0 :(得分:0)

答案离您的方法不远。您可能缺少的运算符是$addToSet运算符,它在这样的阶段中使用(还有一些关于您所做的事情的解释):

db.collection.aggregate([

   {"$group":{
        "_id": {

            // This is conditionally setting the _id
            "$cond":[
                // Where between this range
                {"$and":[
                    {"$gte": ["$time", ISODate("2014-02-15T00:00:00Z")]},
                    {"$lt" : ["$time", ISODate("2014-03-01T00:00:00Z")]}
                ]},
                // Set to season1
                "season1",
                // Otherwise ...  
                {"$cond":[
                    // if between this range
                    {"$and":[
                        {"$gte": ["$time", ISODate("2014-03-01T00:00:00Z")]},
                        {"$lt" : ["$time", ISODate("2014-03-15T00:00:00Z")]}
                    ]},
                    // Then it's season2
                    "season2",
                    // otherwise we don't know what it is
                    null
                ]}
            ]
        },
        // Just counting the items in the results
        "count": {"$sum": 1},
        // Now get the users
        "users": {"$addToSet": "$user" }          // Just the unique ones
    }},

    // De-normalise the users from the set
    {"$unwind": "$users" },

    // Now we want to sum things again
    {"$group": { 
        "_id": "_$id",
        "count": {"$first": "$count" },
        "userCount": {"$sum": 1 }
    }}

])

因此,在我们添加以使事物变得独特之后,数组会解开,这使得之前的文档就像之前的文档一样,除了 unique < / strong>用户现在。

最后一步是我们只需对每个项目1的值求和,计算用户条目。所有userCount条目都是相同的,因此当我们$group时,您只需选择其中一条。

最终结果还包括唯一用户数。