2014-09-05 77 views
1

我正在使用MongoDB聚合框架来聚合一组记录。MongoDB今天的聚合记录

相关的代码片段是:

Record._get_collection().aggregate([ 
     { "$match": { 
      "system_id": system.id 
     }}, 
... 

如何转变这总记录今天只有

一个Record文档具有utc_timestamp场,所以我认为这会是这样的:

Record._get_collection().aggregate([ 
     { "$match": { 
      "system_id": system.id, 
      { "$dayOfMonth": "$utc_timestamp" }: 5 
     }}, 
... 

这是正确的吗?

+0

utc_timestamp字段的格式是什么? – 2014-09-06 01:15:40

回答

2

为了刚刚获得当天的记录,您仍然基本上需要传递一个日期范围,表示一天的开始时间和范围的结束时间。假设你已经在你的班上有DateTimeField随后的MongoDB将使用BSON date类型,是与日汇聚运营商兼容实现这一点:

Record._get_collection().Aggregate([ 
    { "$match": { 
     "system_id": system.id, 
     "utc_timestamp": { 
      "$gte": datetime.datetime(2014,9,6) 
      "$lt": datetime.datetime(2014,9,7) 
     } 
    }}, 
    { "$group": { 
     "_id": { "$dayOfYear": "$utc_timestamp" } 
     .... 

$group一级,这些运营商在汇总值时,通常最有意义比一天更宽的范围,或者在一天内以小时或分钟为单位。否则,由于日期已被选中,因此所有内容都是当天,任何其他字段或值的聚合键实际上都是在当天汇总的。

相反,如果由“时间戳”你确实有代表纪元以来的秒数(BSON类型实际上在内部使用纪元以来的毫秒数),那么你可以构建您的查询是这样的:

Record._get_collection().Aggregate([ 
    { "$match": { 
     "system_id": system.id, 
     "utc_timestamp": { 
      "$gte": (datetime.datetime(2014,9,6) 
        - datetime.datetime(1970,1,1)).total_seconds() 
      "$lt": (datetime.datetime(2014,9,7) 
        - datetime.datetime(1970,1,1)).total_seconds() 
     } 
    }}, 
    { "$group": { 
     "_id": { 
      "$subtract": [ 
       "$utc_timestamp", 
       { "$mod": [ 
        "$utc_timestamp", 
        60 * 60 * 24 
       ]} 
      ] 
     }, 
     ... 

或类似的通过乘以1000来调整更为通用的历元时间戳格式的毫秒。对于通过将匹配的时间戳值四舍五入到当前日期来应用标准“日期数学”的分组。

最后,MongoEngine支持ComplexDateTimeField,它保留了python datetime对象通常可用的微秒数。有点不幸的是,在这种情况下,MongoDB中的实际存储是一个“字符串”,因此数学或一般日期操作符都不可用。但是字符串被格式化为YYYY,MM,DD,HH,MM,SS,NNNNNN,这至少是“词汇”排序,因此可以范围内选择,并用$substr解剖以聚集以每天,或其它周期:

Record._get_collection().Aggregate([ 
    { "$match": { 
     "system_id": system.id, 
     "utc_timestamp": { 
      "$gte": "2014,09,06", "$lt": "2014,09,07" 
     } 
    }}, 
    { "$group": { 
     "_id": { "$substr": [ "$utc_timestamp", 0, 10 ] } 
     ... 

但是,如果使用的是任何其他形式的字符串,那么你将有问题,因为它不可能很好地转换为查询匹配或分组键选择。在这种情况下,您最好将任何此类字符串转换为使用上述表单之一,并明显偏好使用本机BSON日期类型,因为这是最好的支持形式。