简体   繁体   English

pymongo group by datetime

[英]pymongo group by datetime

Im trying to search through a collection and group records by date field which is a datetime. 我试图通过日期字段搜索集合和组记录,这是一个日期时间。 I know pymongo converts those to the proper type on the background (ISODate or something like that). 我知道pymongo会在背景上将那些转换为正确的类型(ISODate或类似的东西)。

Question is, since datetime objects have date, time, timezone.. how can i tell the group operator to use only the date portion? 问题是,因为datetime对象有日期,时间,时区..我怎么能告诉组操作员只使用日期部分? Because otherwise i dont get the desired grouping since time is preventing the records with same day, month, year to be grouped together. 因为否则我没有得到所需的分组,因为时间阻止将同一天,月,年的记录组合在一起。

db.test.aggregate([
        {"$group": {
             "_id": "$date", 
             "count": {"$sum": 1}
        }},
        {"$limit": 10}])

Result: 结果:

{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}]}

It would be nice to control the datetime information used to group, 控制用于分组的日期时间信息会很好,

  • group by date only 仅按日期分组
  • group by date and hour 按日期和小时分组
  • group by date, hour and minute 按日期,小时和分钟分组
  • etc. 等等

Is there something like: (or some way of telling to use date only) 是否有类似的东西:(或某种方式告诉仅使用日期)

db.test.aggregate([
          {"$group": {
              "_id": "$date.date()",
              "count": {"$sum": 1}
          }},
          {"$sort": "_id"}
])

Or maybe there's another way of dealing with this, any ideas? 或者也许有另一种处理这个问题的方法,任何想法? Thanks. 谢谢。

Yes. 是。 You can use the Date Operators with $substr and $concat to tie it all together. 您可以将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 }}
])

You could use just the date operators and make a document as in: 您可以只使用日期运算符并生成文档,如下所示:

"day": { 
    "year": {"$year": "$date" },
   "month": {"$month": "$date"}, 
   "day": {"$dayOfYear": "$date"}
}

That works just as well. 这也很有效。 But this gives you a nice string. 但这会给你一个很好的字符串。 This makes use of the fact that $substr will cast from integer to string. 这利用了$substr将从整数转换为字符串的事实。 If that ever gets added to the documentation. 如果它被添加到文档中。

Look at the Date Operators documentation for usage on the other time divisions that can be used on dates. 查看Date Operators文档,了解可在日期使用的其他时间段的用法。


Better yet, use date math to return a BSON Date: 更好的是,使用日期数学返回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 } }
])

Here datetime.datetime.utcfromtimestamp(0) will be fed into the pipeline as a BSON Date representing "epoch". 这里datetime.datetime.utcfromtimestamp(0)将作为表示“纪元”的BSON日期送入管道。 When you $subtract one BSON Date from another the difference in milliseconds is returned. $subtract另一个BSON日期中$subtract一个BSON日期时,将返回以毫秒为单位的差异。 This allows you to "round" the date to the current day by again subtracting the $mod result to get the remainder of milliseconds difference from a day. 这允许您通过再次减去$mod结果来将日期“舍入”到当前日期,以获得与一天相差的剩余毫秒数。

The same is true of $add where "adding" a BSON Date to a numeric value will result in a BSON Date. $add也是如此,其中“将BSON日期”添加到数值将导致BSON日期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM