MongoDB Scema Design - 查询用户信息和月度统计信息

MongoDB Scema Design - 查询用户信息和月度统计信息

问题描述:

在我们的mongodb数据库中,我们有一组用户。每个用户文档都包含有关用户的一些基本信息,例如位置,出生日期和性别。它包含一些额外的属性,但这是我们存储的数据类型。MongoDB Scema Design - 查询用户信息和月度统计信息

我们也为每个用户收集每月的统计数据。我们为用户收集了许多不同的统计数据,但总体思路是每个月都会有一个文档供每个用户使用。该文档将包含许多不同的属性,主要包含数字数据。这里是一个月度文档的例子。

{ 
    "UserId": ObjectId(""), 
    "SummaryDate": ISODate("2014-09-01T04:00:00Z"), 
    TotalViews: 34, 
    Points: 300, 
    Growth: 20.3 
} 

业务想根据统计信息查询用户。我过去使用过mongodb,但不是用于此用途。我的第一个想法是将其他属性合并到每月统计信息收集中,但想知道其他人的想法。

一些示例报告

  • 给我在密歇根州的所有用户,他们的起始月份和结束月份之间增长(每月汇总统计)是大于X.
  • 给我的所有用户在密歇根州和表演我的统计数据为6月,7月和8月,我们希望能够按特定月份的统计数据进行排序。表如下所示: [ Full Name | Location | June 2014 Views | June 2014 Growth | July 2015 | July 2015 Growth ]

欣赏你的想法。

编辑:我也必须支持某种形式的分页和排序的所有领域。

+1

做排序的维查询你需要或者保持在摘要中的文件,这些属性(如果没有太多请记住它们应该被编入索引,这会减慢写入的速度)*或*您可能会查询用户标识的相应属性,然后仅查询您希望的用户标识的汇总集合,但如果您有例如,来自密歇根州的数百万用户。我会建议保留摘要文档中的属性。 – 2014-10-07 15:39:23

+0

谢谢。我看到的唯一问题是分页和排序。如果他们要对用户过滤的数据进行排序很容易,但是如果他们在统计信息列上进行排序,则会按照第一批用户中包含的用户进行排序。 – 2014-10-07 19:09:10

+0

似乎是[MongoDB的聚集管道]的候选人(http://docs.mongodb.org/manual/core/aggregation-introduction/)。 – zamnuts 2014-10-07 19:14:04

要进行维度查询,您需要在摘要文档中保留这些属性(假设它们不是太多,因为它们应该被编入索引,这会减慢写入的速度)。

因此,假设一个文件:

{ 
    "UserId": ObjectId(""), 
    "FullName":"Joe Shmoe", 
    "Location":"Michigan", 
    "SummaryDate": ISODate("2014-09-01T04:00:00Z"), 
    TotalViews: 34, 
    Points: 300, 
    Growth: 20.3 
} 

要做到基于状态的第二查询将是这样的:

在密歇根州(任选的其它属性过滤器)的所有用户,并告诉我他们的统计6月,7月和8月按7月份的统计数据排序。

db.collection.aggregate([ 
    {"$match":{ 
     "Location":"Michigan", 
     "SummaryDate":{"$gt":ISODate("2014-06-01T04:00:00Z"), "$lt":ISODate("2014-09-01T04:00:00Z")} 
    } }, 
    {"$group": { 
     "_id":"$UserId", 
     "Full Name":{$first:"$FullName"}, 
     "Location":{$first:"$Location"}, 
     "June views": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},6]},then:"$TotalViews",else:0}}}, 
     "June growth": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},6]},then:"$Growth",else:0}}}, 
     "July views": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},7]},then:"$TotalViews",else:0}}}, 
     "July growth": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},7]},then:"$Growth",else:0}}}, 
     "Aug views": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},8]},then:"$TotalViews",else:0}}}, 
     "Aug growth": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},8]},then:"$Growth",else:0}}}, 
    } }, 
    {"$sort":{"July views":1} } 
]); 

输出将文件是这样的样本名单:

{ 
    "_id" : ObjectId("543445dd19b404b29e503f94"), 
    "Full Name" : "Jane Shmoe", 
    "Location" : "Michigan", 
    "June views" : 0, 
    "June growth" : 0, 
    "July views" : 40, 
    "July growth" : 20.3, 
    "Aug views" : 340, 
    "Aug growth" : 20.3 
} 
+0

非常感谢您对此的反馈。伟大的,有用的例子。欣赏它。 – 2014-10-07 20:34:21