2014-07-14 92 views
3

我試圖用日期聚合運算符調整時區。 我需要在$signs.timestamp字段上進行-7小時的調整。mongodb日期彙總運算符使用php的時區調整

這是我的代碼:

function statsSignatures() { 
    $cursor = $this->db->collection->users->aggregate(
     array('$unwind' => '$signs'), 
     array('$project'=>array(
      'signs'=>'$signs', 
      'y'=>array('$year'=>'$signs.timestamp'), 
      'm'=>array('$month'=>'$signs.timestamp'), 
      'd'=>array('$dayOfMonth'=>'$signs.timestamp'), 
      'h'=>array('$hour'=>'$signs.timestamp') 
     )), 
     array('$group'=>array(
      '_id'=>array('year'=>'$y','month'=>'$m','day'=>'$d','hour'=>'$h'), 
      'total'=>array('$sum'=>1) 
     )), 
     array('$sort'=>array(
      '_id.year'=>1, 
      '_id.month'=>1, 
      '_id.day'=>1, 
      '_id.hour'=>1 
     )) 
    ); 
    return $cursor['result']; 
} 

我使用MongoDB的版本2.6.3。

非常感謝!

+0

是,時區的問題往往是具有挑戰性的。但是,正如目前所寫,很難說出你在問什麼。請閱讀[我如何問一個好問題?](http://stackoverflow.com/help/how-to-ask)和[如何創建最小,完整和可驗證的示例](http:// stackoverflow。 com/help/mcve),然後回來編輯你的問題。謝謝。 –

+0

$ signs.timestamp是mongodate對象。我需要在分組前對其進行-7小時調整 –

+0

您確定嗎?您是否認爲在夏令時期間有許多時區遵循不同的偏移量?例如,美國山地時間(亞利桑那州大部分地區除外)在標準時間爲-7,在白天爲-6。 –

回答

5

您可以使用$project$subtract運營商做出-7小時調整日期字段:

{ 
    $project : { 
     ts : { $subtract : [ "$signs.timestamp", 25200000 ] } 
    } 
} 

// 25200000 == 1000 milis x 60 sec x 60 mins x 7 h 

投影領域ts是可以被-7小時偏移的日期。

編輯

這是正確的PHP語法使用$減時。

array(
    '$project' => array( 
     'ts' => array('$subtract' => array('$signs.timestamp', 25200000)) 
    ) 
) 

減法接受值的數組,而不是鍵=>值對。

+0

代碼: 陣列( '$項目'=>數組( 'TS'=>數組( '$減法'=>數組( '$ signs.timestamp'=> 25200000 )) )) I」 m得到異常「例外:無效的運營商'$ signs.timestamp'」 –

+0

理論上這是正確的答案。但我已經嘗試了很多方法來做到這一點在PHP上,它不工作。 –

+1

@Zukas我用正確的PHP語法更新了我的答案。 –

0

我不知道爲什麼,但我發現了「異常:無效運算符‘$ signs.timestamp’」如果我想減去該在php這樣的代碼:

 $cursor = $app['mdb']->changemi->users->aggregate(
      array('$unwind' => '$signs'), 

      array('$project' => array(
       'ts'=>array('$subtract'=>array(
        '$signs.timestamp'=> 25200000 
       )) 
      )), 
      array('$project'=>array(
       'y'=>array('$year'=>'$ts'), 
       'm'=>array('$month'=>'$ts'), 
       'd'=>array('$dayOfMonth'=>'$ts'), 
       'h'=>array('$hour'=>'$ts') 
      )), 
      array('$group'=>array(
       '_id'=>array('year'=>'$y','month'=>'$m','day'=>'$d','hour'=>'$h'), 
       'total'=>array('$sum'=>1) 
      )), 
      array('$sort'=>array(
       '_id.year'=>1, 
       '_id.month'=>1, 
       '_id.day'=>1, 
       '_id.hour'=>1 
      )) 
     ); 

所以我帶來了兩種解決方法:

  1. 後端php。 json_decode

    $cursor = $app['mdb']->changemi->users->aggregate(
         array('$unwind' => '$signs'), 
         json_decode('{"$project" : {"ts" : { "$subtract" : [ "$signs.timestamp", 25200000 ] }}}',true), 
         array('$project'=>array(
          'y'=>array('$year'=>'$ts'), 
          'm'=>array('$month'=>'$ts'), 
          'd'=>array('$dayOfMonth'=>'$ts'), 
          'h'=>array('$hour'=>'$ts') 
         )), 
         array('$group'=>array(
          '_id'=>array('year'=>'$y','month'=>'$m','day'=>'$d','hour'=>'$h'), 
          'total'=>array('$sum'=>1) 
         )), 
         array('$sort'=>array(
          '_id.year'=>1, 
          '_id.month'=>1, 
          '_id.day'=>1, 
          '_id.hour'=>1 
         )) 
        ); 
    
  2. 前端的JavaScript(minusHours)

    Date.prototype.minusHours= function(h){ 
        this.setHours(this.getHours()-h); 
        return this; 
    } 
    

...

  "date": new Date({{ i._id.year }}, {{ i._id.month -1 }}, {{ i._id.day }}, {{ i._id.hour }}, 0, 0, 0).minusHours(7), 
0

這裏是我工作。而不是在'項目'中進行時區轉換,我只是在分組時轉換時間戳。

group._id = { 
    year: { $year : [{ $subtract: [ "$timestamp", 25200000 ]}] }, 
    month: { $month : [{ $subtract: [ "$timestamp", 25200000 ]}] }, 
    day: { $dayOfMonth : [{ $subtract: [ "$timestamp", 25200000 ]}] } 
}; 

group.count = { 
    $sum : 1 
}; 
0

沒有必要關閉在陣列的一些對象,這樣一來爲我工作:

group._id = { 
    year: { $year : { $subtract: [ "$timestamp", 25200000 ]}}, 
    month: { $month : { $subtract: [ "$timestamp", 25200000 ]}}, 
    day: { $dayOfMonth : { $subtract: [ "$timestamp", 25200000 ]}} 
}; 

group.count = { 
    $sum : 1 
};