我的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的情况下执行此操作?
答案 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
时,您只需选择其中一条。
最终结果还包括唯一用户数。