你似乎只是想從結果返回的時間戳值。確實有一種簡單的方法可以在不使用date aggregation operators的情況下在聚合框架中執行此操作。您可以使用基本的「日期的功能」,而是和與可用於提取日期對象的「時間戳」值,並操縱它一招:
db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$time", new Date("1970-01-01") ] },
{ "$mod": [
{ "$subtract": [ "$time", new Date("1970-01-01") ] },
1000 * 60 * 60 * 24
]}
]
},
"avg": { "$avg": "$TEMP_C" }
}}
])
所以基本的「絕招」也就是當從另一個(或類似操作)中減去一個日期對象,則返回的結果是兩個時間差的「毫秒」的數字。因此,通過使用「1970-01-01」的「epoch」日期,您可以將日期對象的「epoch timestamp」值作爲數字。
然後,通過從這個值中減去一天中的毫秒數模(或餘數)來應用基本日期數學。這會「舍入」該值以表示記錄條目的「日期」。
我喜歡張貼JSON,因爲它解析無處不在,但在更多的PHP的方式,則是這樣的:
$collection->aggregate(array(
array('$group' => array(
'_id' => array(
'$subtract' => array(
array('$subtract' => array(
'$time', new MongoDate(strtotime("1970-01-01 00:00:00"))
)),
array( '$mod' => array(
array('$subtract' => array(
'$time', new MongoDate(strtotime("1970-01-01 00:00:00"))
)),
1000 * 60 * 60 * 24
))
)
),
"avg" => array('$avg' => '$TEMP_C')
))
))
因此比使用日期匯聚運營商獲得您想要的結果一點清潔劑。當然,這仍然不是「一路」如何讓數據呈現在您可以在客戶端使用的位置。
這裏要做的真實情況是操縱結果,以便獲得所需的輸出格式。這可能是更適合您的服務器代碼做處理返回的響應之前,但如果你有MongoDB的2.6或更大的則是「可能」做到這一點聚合管道本身:
db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$time", new Date("1970-01-01") ] },
{ "$mod": [
{ "$subtract": [ "$time", new Date("1970-01-01") ] },
1000 * 60 * 60 * 24
]}
]
},
"avg": { "$avg": "$TEMP_C" }
}},
{ "$group": {
"_id": null,
"data": {
"$push": {
"$map": {
"input": { "$literal": [ 1,2 ] },
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el", 1 ] },
"$$_id",
"$avg"
]
}
}
}
}
}}
])
所以這真的很狡猾。在完成初始「分組」以確定每天的平均值後,您每天會在結果文檔中獲得兩個字段,分別爲_id
和avg
。這裏的$map
運算符是以數組和輸入爲輸入(在這種情況下,只是一個帶有一對數值的編號模板來標識位置),並處理每個元素以返回一個與原始數據相同的數組。
這裏的$cond
運算符允許您查看該數組的當前元素的值,並將其與當前文檔中存在的另一個值「交換」。因此,對於每個文檔,結果包含的東西,就像是一個配對數組:
[ 1409346800000, 12 ]
然後,所有發生的一切結果如下推入一個「數據」陣列中的單個文件顯示:
{ "_id": null, "data": [ [..,..], [..,..], (...) ] }
現在,您在那一個結果中的數據元素是一個代表您想要的點的數組對。
當然雖然,像$map
運營商只能從MongoDB的2.6及以後的,所以如果你有一個可用的,那麼你可以使用它們,但否則只好處理代碼中的結果具有相似的「地圖」操作:
function my_combine($v) {
return array($v["_id"],$v["avg"])
}
$newresult = array_map("my_combine", $result)
所以這真的歸結爲數組操作,無論你使用哪種方法,但日期操作技巧也應該爲您節省一些工作,以獲得結果作爲預期的時間戳值。
感謝您的詳細解答。確實很有幫助。第一部分,關於日期 - 時間的數學運作完美。正如你所說,訣竅是減去日期返回毫秒(不是日期)。我想我會將新日期('1970 ...')聲明爲全局或常量,以便在其他情況下使用它。根據第二部分(組和地圖),它確實不是必需的。我認爲這太過分了。 $ group by _id,$ project('_id'=> 0,0 =>'$ _id',1 =>'$ avg')結束了在管道中添加了兩個階段 - 刪除陣列中的鍵名對於Highcharts來說已經足夠了;) – 2014-10-03 19:45:42
@s_mdq Well Overkill是我基本上描述它的方式,而PHP array_map正在做同樣的事情以實質上刪除鍵。真的只是在那裏表明,它可以基本上完成。 – 2014-10-04 00:23:17