Seb*_*ian 4 python mongodb pymongo mongodb-query aggregation-framework
我试图通过日期字段搜索集合和组记录,这是一个日期时间.我知道pymongo会在背景上将那些转换为正确的类型(ISODate或类似的东西).
问题是,因为datetime对象有日期,时间,时区..我怎么能告诉组操作员只使用日期部分?因为否则我没有得到所需的分组,因为时间阻止将同一天,月,年的记录组合在一起.
db.test.aggregate([
{"$group": {
"_id": "$date",
"count": {"$sum": 1}
}},
{"$limit": 10}])
Run Code Online (Sandbox Code Playgroud)
结果:
{u'ok': 1.0,
u'result': [
{u'_id': datetime.datetime(2014, 2, 15, 18, 49, 9, tzinfo=<bson.tz_util.FixedOffset object at 0x318f210>),
u'count': 1},
{u'_id': datetime.datetime(2014, 2, 15, 18, 36, 38, tzinfo=<bson.tz_util.FixedOffset object at 0x318f210>),
u'count': 1},
{u'_id': datetime.datetime(2014, 2, 15, 18, 23, 56, tzinfo=<bson.tz_util.FixedOffset object at 0x318f210>),
u'count': 1}]}
Run Code Online (Sandbox Code Playgroud)
控制用于分组的日期时间信息会很好,
是否有类似的东西:(或某种方式告诉仅使用日期)
db.test.aggregate([
{"$group": {
"_id": "$date.date()",
"count": {"$sum": 1}
}},
{"$sort": "_id"}
])
Run Code Online (Sandbox Code Playgroud)
或者也许有另一种处理这个问题的方法,任何想法?谢谢.
是.您可以将Date Operators与$ substr和$ concat结合使用.
db.test.aggregate([
{"$group": {
"_id" : { "$concat": [
{"$substr": [{"$year": "$date"}, 0, 4 ]},
"-",
{"$substr": [{"$month": "$date"}, 0, 2 ]},
"-",
{"$substr": [{"$dayOfMonth": "$date"}, 0, 2 ]},
]},
"count": {"$sum": 1 }
}},
{"$sort": { "_id": 1 }}
])
Run Code Online (Sandbox Code Playgroud)
您可以只使用日期运算符并生成文档,如下所示:
"day": {
"year": {"$year": "$date" },
"month": {"$month": "$date"},
"day": {"$dayOfYear": "$date"}
}
Run Code Online (Sandbox Code Playgroud)
这也很有效.但这会给你一个很好的字符串.这利用了$substr将从整数转换为字符串的事实.如果它被添加到文档中.
查看Date Operators文档,了解可在日期使用的其他时间段的用法.
更好的是,使用日期数学返回BSON日期:
import datetime
db.test.aggregate([
{ "$group": {
"_id": {
"$add": [
{ "$subtract": [
{ "$subtract": [ "$date", datetime.datetime.utcfromtimestamp(0) ] },
{ "$mod": [
{ "$subtract": [ "$date", datetime.datetime.utcfromtimestamp(0) ] },
1000 * 60 * 60 * 24
]}
]},
datetime.datetime.utcfromtimestamp(0)
]
},
"count": { "$sum": 1 }
}},
{ "$sort": { "_id": 1 } }
])
Run Code Online (Sandbox Code Playgroud)
这里datetime.datetime.utcfromtimestamp(0)将作为代表"纪元"的BSON日期送入管道.当您$subtract从另一个BSON Date开始时,将返回以毫秒为单位的差异.这允许您通过再次减去$mod结果来将日期"舍入"到当天,以获得与一天相差的剩余毫秒数.
将$addBSON日期"添加"到数值的位置也会产生BSON日期.