MongoDB中重叠日的聚合查询

时间:2016-04-14 14:21:58

标签: mongodb mongodb-query aggregation-framework

我为几乎实时的统计模块创建数据库结构。我想计算不同产品的用户行为:新喜欢,投票,新评论和总活动(投票总数,喜欢等)。

模块需要在过去8,16或24小时内发回最多活动 N个产品。 我的第一个想法是文档的以下模式:

{
    "_id" : ObjectId("570e37d0db8c0897d651509c"),
    "date" : "2016-04-13",
    "trackId" : 35,
    "count" : {
        "hour_1" : {
            "total" : 120,
            "downVote" : 35,
            "newComment" : 26,
            "upVote" : 34,
            "like" : 25
        },
        "hour_2" : {
            "total" : 124,
            "downVote" : 32,
            "like" : 28,
            "upVote" : 33,
            "newComment" : 31
        },
        // ...
        "hour_24" : {
            "total" : 119,
            "downVote" : 42,
            "newComment" : 30,
            "upVote" : 31,
            "like" : 16
        }
    }
}

在这种情况下,我有一天X产品的X文档,通过这个查询,我可以快速获取我需要的数据。

db.getCollection('HourlyStat')
  .aggregate([
    {$match: {date: '2016-04-13'}}, 
    {
      $project: {'trackId': "$trackId", 
      count: {
        $sum: ["$count.hour_1.total", "$count.hour_2.total", ..., "$count.hour_8.total"] } 
      } 
    }, 
    {$sort: {'count': -1}}, {$limit: 10}
  ])

不幸的是,这不适用于包括两天的时间段。 例如:从2016-04-13 12:00:002016-04-14 12:00:00

我可以为此编写查询,还是应该更改数据结构?一个简单的解决方法是将每小时数据存储在独立文档中,但它将包含24倍以上的数据,对于大量产品,它可能会很慢。

1 个答案:

答案 0 :(得分:0)

我认为您需要按照您对独立文档中每小时数据的建议更改架构。您还应该为日期使用正确的日期()字段,这样您就可以更灵活地使用基于日期的查询。

db.getCollection('HourlyStat')
  .aggregate([
    {$match: {date: {$gt: new Date(new Date()-1000*60*60*24 )}}}
    //...
    ])

如果更容易,您还可以在客户端生成搜索的开始结束时间,而不是限制到最近n小时。这样做的好处是查询更简单(我喜欢简单的查询)

db.getCollection('dates')
  .aggregate([
    {$match: {date: {$gte: ISODate("2016-04-13T09:00:00.000+0000"), $lt: ISODate("2016-05-16T20:00:00.000+0000") }}}
    ])