Python 按日期时间划分的pymongo组

Python 按日期时间划分的pymongo组,python,mongodb,mongodb-query,aggregation-framework,pymongo,Python,Mongodb,Mongodb Query,Aggregation Framework,Pymongo,我正试图通过日期字段搜索集合和分组记录,该字段是日期时间。 我知道pymongo会在后台将其转换为正确的类型(ISODate或类似的类型) 问题是,因为datetime对象有日期、时间和时区。。如何告诉组操作员仅使用日期部分?因为否则我无法得到所需的分组,因为时间阻止了将具有相同日期、月份、年份的记录分组在一起 db.test.aggregate([ {"$group": { "_id": "$date", "count":

我正试图通过日期字段搜索集合和分组记录,该字段是日期时间。 我知道pymongo会在后台将其转换为正确的类型(ISODate或类似的类型)

问题是,因为datetime对象有日期、时间和时区。。如何告诉组操作员仅使用日期部分?因为否则我无法得到所需的分组,因为时间阻止了将具有相同日期、月份、年份的记录分组在一起

db.test.aggregate([
        {"$group": {
             "_id": "$date", 
             "count": {"$sum": 1}
        }},
        {"$limit": 10}])
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 }}
])
结果:

{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}]}
或者也许有其他方法来解决这个问题,有什么想法吗? 谢谢。

是的。您可以使用with和将其连接在一起

db.test.aggregate([
        {"$group": {
             "_id": "$date", 
             "count": {"$sum": 1}
        }},
        {"$limit": 10}])
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 }}
])
您可以只使用日期运算符,并制作文档,如中所示:

"day": { 
    "year": {"$year": "$date" },
   "month": {"$month": "$date"}, 
   "day": {"$dayOfYear": "$date"}
}
这同样有效。但这给了你一条漂亮的线。这利用了
$substr
将从整数转换为字符串这一事实。如果这被添加到文档中

查看文档,了解可用于日期的其他时间段的用法


更好的方法是使用日期数学返回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 } }
])
此处将作为代表“纪元”的BSON日期输入管道。当您将一个BSON日期与另一个BSON日期进行比较时,将返回以毫秒为单位的差值。这允许您通过再次减去结果来获得一天的剩余毫秒差,从而将日期“舍入”到当前日期

如果将BSON日期“添加”到数值将导致BSON日期,则情况也是如此。

谢谢!这非常有效(我已经修复了$substr上的括号)