MongoDB的聚合框架

时间:2013-05-15 05:39:24

标签: mongodb

我有以下架构:

Customer ID
Location Name
Time of Visit

以上信息存储了所有客户在不同地点的访问信息。

我想知道是否有办法在MongoDB中编写聚合查询,以便它按当天不同部分(每天每个位置)提供总访问者信息。

当天的部分:

编辑:

12 am  -  8 am
8 am   -  11 am
11 am  -  1 pm
1 pm   -  4 pm
4 pm   -  8 pm
8 pm   -  12 pm

如果客户在同一天和同一天的同一部分多次访问某个位置,则应仅计算一次。但是,如果该客户在同一天访问某个位置但是在当天的不同部分访问某个位置,那么对于他出现的那一天中的每个部分,应该只计算一次。

示例:

Customer 1 visits store A on day 1 at 9:30 AM
Customer 1 visits store A on day 1 at 10:30 PM
Customer 1 visits store B on day 2 at 9:30 AM
Customer 1 visits store B on day 2 at 11:30 AM
Customer 1 visits store B on day 2 at 2:45 PM

Customer 2 visits store A on day 1 at 9:45 AM
Customer 2 visits store B on day 1 at 11:00 AM
Customer 2 visits store B on day 2 at 9:45 AM

重复访问的最终结果:

Store B, Day 1, Section (00:00 - 08:00) : 0 Visitors
Store B, Day 1, Section (08:00 - 16:00) : 2 Visitors
Store B, Day 1, Section (16:00 - 24:00) : 1 Visitors
Store B, Day 2, Section (00:00 - 08:00) : 0 Visitors
Store B, Day 2, Section (08:00 - 16:00) : 2 Visitors
Store B, Day 2, Section (16:00 - 24:00) : 0 Visitors

有没有办法可以使用MongoDB的聚合框架完成上述类型的查询?

1 个答案:

答案 0 :(得分:1)

是的,这可以很简单地完成。它与我在answer to your previous question中描述的查询非常相似,但不是按天聚合,而是需要按日 - 小时组合进行汇总。

首先,您需要投射一个新的日期部分,而不是做一个组,您需要将“访问时间”字段转换为适当的小时表格。让我们看一下这样做的方法:

{$project : { newDate: {
                  y:{$year:"$tov"}, m:{$month:"$tov"}, d:{$dayOfMonth:"$tov"}, 
                  h: { $subtract : 
                          [ { $hour : "$tov" }, 
                            { $mod : [ { $hour : "$tov" }, 8 ] } 
                          ] 
                     }
             },
             customerId:1, locationId:1 
           }
}

正如你所看到的那样,它会生成年,月,日和小时,但小时会被截断为mod 8(所以你得到0,8(上午)或16下午4点。

接下来,我们可以执行之前执行的相同步骤,但现在我们将聚合到不同级别的时间粒度。

还有其他方法可以实现相同的目标,您可以在我的博客上看到some examples of date manipulation