4

我正在尋找這個,但找不到有用的東西來解決我的情況。我想要的是在聚合過程中,在MongoDB ISODate之外獲得unix時間戳。問題是,我可以從ISODate中獲取時間戳,但是它的時間間隔爲毫秒。所以我需要削減那些毫秒。我已經試過是:在聚集過程中獲取MongoDB ISODate的秒數unix時間戳

> db.data.aggregate([ 
    {$match: {dt:2}}, 
    {$project: {timestamp: {$concat: [{$substr: ["$md", 0, -1]}, '01', {$substr: ["$id", 0, -1]}]}}} 
    ]) 

正如你可以看到,我試圖讓戳出來的「MD」 var和也與「01」和「ID」號碼拼接這個時間戳。上面的代碼給出:

{ 
    "_id" : ObjectId("52f8fc693890fc270d8b456b"), 
    "timestamp" : "2014-02-10T16:20:56011141" 
} 

然後我改善了與命令:

> db.data.aggregate([ 
    {$match: {dt:2}}, 
    {$project: {timestamp: {$concat: [{$substr: [{$subtract: ["$md", new Date('1970-01-01')]}, 0, -1]}, '01', {$substr: ["$id", 0, -1]}]}}} 
    ]) 

現在,我得到:

{ 
    "_id" : ObjectId("52f8fc693890fc270d8b456b"), 
    "timestamp" : "1392049256000011141" 
} 

我真正需要的是1392049256011141所以沒有3個額外的000。我試過用$減號:

> db.data.aggregate([ 
    {$match: {dt:2}}, 
    {$project: {timestamp: {$concat: [{$substr: [{$divide: [{$subtract: ["$md", new Date('1970-01-01')]}, 1000]}, 0, -1]}, '01', {$substr: ["$id", 0, -1]}]}}} 
    ]) 

我得到的是:

{ 
    "_id" : ObjectId("52f8fc693890fc270d8b456b"), 
    "timestamp" : "1.39205e+009011141" 
} 

不完全是我所期望的命令。不幸的是,$ substr運算符不允許負長度。有沒有人有任何其他解決方案?

回答

7

我不知道爲什麼你認爲你需要在幾秒鐘內,而不是毫秒值通常這兩種形式是有效的,大多數語言實現毫秒實際上是首選之內。但一般來說,試圖強迫成一個字符串,這是錯誤的方式去解決這個問題,一般你只是做數學題:

db.data.aggregate([ 
    { "$project": { 
    "timestamp": { 
     "$subtract": [ 
     { "$divide": [ 
      { "$subtract": [ "$md", new Date("1970-01-01") ] }, 
      1000 
     ]}, 
     { "$mod": [ 
      { "$divide": [ 
       { "$subtract": [ "$md", new Date("1970-01-01") ] }, 
       1000 
      ]}, 
      1 
     ]} 
     ] 
    } 
    }} 
]) 

它返回您在幾秒鐘內一個劃時代的時間戳。基本上來自一個BSON日期對象從另一個BSON日期對象中減去時的結果是以毫秒爲單位的時間間隔。使用「1970-01-01」的初始紀元日期基本上從當前日期值中提取毫秒值。 $divide運算符實際上取消了毫秒部分,並且$mod執行模數來實現舍入。

真的,儘管您最好用本機語言爲您的應用程序完成這項工作,因爲所有BSON日期將作爲本機「日期/日期時間」類型返回,您可以在其中提取時間戳值。考慮JavaScript的基礎知識在shell:

通常採用聚集
var date = new Date() 
(date.valueOf()/1000) - ((date.valueOf()/1000) % 1) 

你想要做這種「數學」,以使用時間戳值類似,如一天的時間內彙總值。有可供聚合框架日期運算符,但你也可以做到這一點的日期數學方式:

db.data.aggregate([ 
    { "$group": { 
     "_id": { 
      "$subtract": [ 
       { "$subtract": [ "$md", new Date("1970-01-01") ] }, 
       { "$mod": [ 
        { "$subtract": [ "$md", new Date("1970-01-01") ] }, 
        1000 * 60 * 60 * 24 
       ]} 
      ] 
     }, 
     "count": { "$sum": 1 } 
    }} 
]) 

這形式是比較典型的發射四捨五入至每天時間戳和聚合這些區間內的結果。

因此,您只是爲了提取時間戳而使用聚合框架的目的似乎不是最好的用法,或者事實上它不應該將其轉換爲秒而不是毫秒。在您的應用程序代碼中,我認爲您應該這樣做,除非您確實需要時間間隔的結果,您可以在其中應用日期數學,如圖所示。

這些方法在那裏,但除非實際上聚合,否則這將是您的應用程序的最差性能選項。改爲使用代碼進行轉換。