2014-02-26 33 views
2

我試圖通過日期時間的日期字段搜索集合和組記錄。 我知道pymongo將這些轉換爲背景上的正確類型(ISODate或類似的東西)。pymongo group by datetime

問題是,因爲datetime對象有日期,時間,時區..我如何告訴組操作員只使用日期部分?因爲否則我沒有得到所需的分組,因爲時間阻止了將同一天,每月,每年的記錄分組在一起。

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

結果:

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

這將是很好的控制用於組的日期時間信息,

  • 組僅按照日期
  • 按日期和時間
  • 按日期,小時,分鐘組

有什麼樣:(或告知使用最新的一些方法只)

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

或者,也許有這個處理,任何想法的另一種方式? 謝謝。

回答

3

是的。您可以將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 }} 
]) 

你可以只使用日期運營商,並作出文檔中:

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

這作品一樣好。但是這給你一個很好的字符串。這利用了$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 } } 
]) 

這裏datetime.datetime.utcfromtimestamp(0)將被送入流水線爲代表「時代」一個BSON日期。當你$subtract一個BSON從另一個日期返回毫秒的差異。這允許您通過再次減去$mod結果來將日期「四捨五入」到當前日期,以獲得與一天之間的其餘毫秒差異。

$add的情況也是如此,其中將「BSON日期」添加到數值會導致BSON日期。

+0

謝謝!這很好(我已經修復了$ substr的括號) – Sebastian