2013-02-20 29 views
16

對於我的一個集合,它必須保持unix時間戳而不是isodate,我通常用新日期(unix_timestamp)轉換時間戳。

現在我需要new Date(ts)在一個聚合。 (例子是在PHP)

'$項目'=>陣列( '天'=> '$新的日期(TS)',...

'$組'=>陣列( 「_id」=> array('day'=>'$ day)',...),...

未到達結果中結果字段「day」完全缺失

如何在彙總內獲得此轉換?

回答

3

對於廣告ditional計算領域的投影需要使用$添加運營商,像這樣: (控制檯例子)

db.so.aggregate([{$project: {date: {$add: Date() }}}]) 

但它是錯誤的,我們得到了一個錯誤信息:

exception: $add does not support strings (or dates) 

但是我發現一個簡單的砍=)

db.so.aggregate([{$project: {date: {$substr: [Date(), 0, -1] }}}]) 

在這種情況下,我們將有日期 也有望因此,在PHP中輸出,您可以看到錯誤是這樣的:

exception: disallowed field type Date in object expression (at 'date') 

而現在,解決方案(PHP 5.4語法):

$so->aggregate([ 
    ['$project' => ["date" => ['$substr' => [new MongoDate(), 0, -1]] ] ] 
]); 
+2

這不會將字段ts的值轉換爲一個mongo日期。它只接受php字符串或數字作爲輸入,而不是來自集合本身的值:/ – ledy 2013-02-20 21:24:01

+0

Ops,抱歉)可能應該使用map-reduce而不是聚合來處理這種情況? – 2013-02-20 21:58:06

+0

@KirillZorin,這太棒了! substr是完美的投影日期,減少時間部分。這非常有幫助! – 2013-05-06 18:15:14

21

能夠從文檔中添加時間戳字段,你可以這樣做,因爲:

{"ts": 1400512120100} 

作爲日期彙總:

db.foo.aggregate({ 
    $project: { 
     date: { $add: [new Date(0), "$ts"] } 
    } 
}) 
+1

這對我幫助很大!我的時間戳都是UTC,我想轉換爲當地時間。我能用這種方法做到這一點。 {$ project:{dd:{$ add:[new Date(0),{$ subtract:[{$ multiply:[「$ items.ordered」,1000]},tzoffset]}]},... – 2014-06-13 17:09:16

+1

我看到這個作品,但是這裏發生了什麼?在'ISODate(「2014-05-19T15:08:40.100Z」)''中,''新日期(1400512120100)'的結果正確。但是,如果您嘗試在不帶'$ add'的'$ project'中使用'new Date()',則會在對象表達式中獲得'不允許的字段類型Date'。根據這個例子,很明顯可以返回日期。如果你在'$ project'中嘗試'$ add:[new Date(「$ ts」)]',你會得到一個很大的負值('ISODate(「 - 292275055-05-16T16:47:03.192Z」)' )。 '$ add'如何正確處理數據類型並返回一個'ISODate'沒有錯誤? – duozmo 2016-02-09 21:41:15

+0

@duozmo:我認爲'new Date()'不起作用的原因是'new Date()'只在管道啓動之前執行一次。只有特殊的MongoDB「聚合運算符」(比如'$ add','$ trunc'等)纔會爲每個值運行。因此,如果您想在彙總期間創建日期,則必須使用這些運算符中的一個。由於MongoDB中沒有運算符'millisecondsToDate',所以您必須(ab)使用'$ add'。 – sleske 2016-08-09 10:22:32