为了仅获取当天的记录,您基本上仍然需要传入一个日期范围,该日期范围表示一天的开始和要查找的范围的结束。假设您已经在您的类中使用 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 值的任何聚合键本质上都是当天的聚合。
如果改为使用“时间戳”,您实际上有一个数字表示自纪元以来的秒数(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 日期时间对象中可用的微秒。不幸的是,在这种情况下,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 日期类型,因为这是最受支持的形式。