我有一个存储在Mongodb上的点击集合,使用这个模式:{userid:。。。日期:。。。}
我想显示一个报告,计算两个日期之间的唯一访问者(具有不同用户ID的访问者在这些日期之间成功)。
输出示例:
访问者数量:。。。点击次数:。。。
该集合的大小约为100万条记录。
我的第一个想法是进行增量mapreduce,以按天计算聚合值。然后用第二个mapreduce来输出最后的结果。
问题是,当在报告上选择一系列日期时,我无法计算出正确的唯一访问者数量。
按天计算的合计值示例:第1天:1位独特访客第2天:2个独特的访客(2个访客中的1个在第1天就成功了)
两天的唯一访客总数为3,但整个期间只有2名唯一访客,而不是3名。
在这个例子中,你有任何计算独特访客的性能方法吗?
通过在所需日期上使用单个映射减少,这个问题可能更容易解决。您可以对要检查的所有日期进行相同的聚合,而不是首先聚合一天的唯一用户(第一步)。这样你就可以完全避免第二步。
将其分解为地图和减少部分:
地图:查找在所需时间范围内记录的所有用户ID
减少:删除所有重复的用户ID
一旦这个过程完成,您应该留下该时间范围内的一组唯一访问者(更具体地说,是唯一的用户ID)。
或者,还有一种更简单的方法可以做到这一点,根本不需要地图缩减。"distinct"命令(请参阅mongoDB distinct文档)允许您选择一个字段,并返回一个只填充该字段的distinct(唯一)值的数组。如果在所需的时间范围内对文档使用distinct命令,您将能够获得一个数组,该数组包含该期间的所有用户ID,并且没有任何重复。
希望这能有所帮助!
使用版本2.2及其聚合框架可以轻松实现这一点。
假设架构{userid:",date:"},并给定两个特定的日期d1和d2,这就是管道:
db.collection.aggregate(
[
{
"$match" : {
"date" : {
"$gte" : d1,
"$lte" : d2
}
}
},
{
"$group" : {
"_id" : "$userid",
"hits" : {
"$sum" : 1
}
}
},
{
"$group" : {
"_id" : "1",
"visitors" : {
"$sum" : 1
},
"hits" : {
"$sum" : "$hits"
}
}
},
{
"$project" : {
"_id" : 0,
"visitors" : 1,
"hits" : 1
}
}
]