我使用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 :(得分: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
级别,这些运营商通常在比一天更广泛的范围内汇总价值时更有意义,或者在一天内以小时或分钟汇总价值。否则,由于已经选择了日期,因此所有内容都是当前日期,而另一个字段或Null
值的任何聚合键实际上都是当天汇总的。
如果改为“timestamp”,你实际上有一个数字代表自纪元以来的秒数(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日期类型,因为这是最佳支持表单。