2017-07-14 283 views
0

我有包含使用$ currentDate插入日期的字段的mongo文檔,所以當我插入文檔時,該字段具有mongo服務器日期。 我想查詢並過濾所有日期字段和服務器日期之間差異超過10分鐘的文檔。MongoDB查詢帶有服務器時間的日期字段

假設該DB:

{ "_id" : 1, "item" : "abc", "price" : 10, "fee" : 2, "discount" : 5, "date" : ISODate("2017-07-14T08:00:00Z") } 
{ "_id" : 2, "item" : "jkl", "price" : 20, "fee" : 1, "discount" : 2, "date" : ISODate("2017-07-14T08:05:00Z") } 

假設我將運行在「2017-07-14T08 01Z:10」查詢我想查詢將只返回的第一個項目是服務器日期, 。

db.items.aggregate([ 
{$project : {lut : {$subtract: ["** server date **", "$date" ]}}}, 
{$match : { lut : {$gte : 10*60*1000 }}} ]); 

如何在運行查詢時獲取服務器日期? 我從我的nodeJS服務器運行查詢,用新的Date()替換服務器日期將獲得節點服務器的日期而不是mongo服務器。

回答

0

MongoDB服務器允許使用爲更新領域$的currentdate運營商,但我沒有找到任何選項來使用日期作爲查詢過濾器。

但有一個選項可以使用「將JavaScript函數存儲在服務器上」https://docs.mongodb.com/manual/tutorial/store-javascript-function-on-server/ 並添加一個將返回日期的函數。

+0

當您有更多信息而不是寫回答時,您可以更新問題。這樣人們在回答你的問題之前就會找到信息。 – bogdanciobanu

2

這比第一眼看起來更棘手。當涉及複製和分片時,很難保證所有Mongo實例上的時鐘之間的完美同步。這就是$ currentDate未被開發團隊[在這張票上]解釋過的查詢擴展的原因。

這就是說,一個完美的解決方案並不存在,但我們可以考慮解決方法。 serverStatus函數返回有關Mongo羣集的信息,包括服務器時間。您可以在初始化客戶端代碼時調用此函數,並查找客戶端時間和服務器時間之間的差異。有了這些差異,您可以根據客戶端時間修正差異來進行查詢。下面是一個Python代碼片段:

import datetime 
import pymongo 
client = pymongo.MongoClient() 
db = client.test_Db 
server_time = db.command("serverStatus")['localTime'] 
local_time = datetime.datetime.now() 
difference = server_time - local_time 


db.test_collection.find({'date': {'$lt': datetime.datetime.now() - datetime.timedelta(minutes=10) + difference}}) 

注意,這有時間在服務器上測量的時刻,它在客戶端上測量的時間之間的誤差。此錯誤受信息從服務器發送到客戶端的持續時間的影響。根據您的用例,您可以從數據庫返回更多或更少的文檔。如果您第一次在客戶端和服務器上獲得時間,您將收到比早10分鐘的文檔+錯誤,因此您將錯過一些文檔。另一方面,如果您首先在服務器上獲取時間,然後在客戶端上獲取時間,則會收到比早10分鐘的文檔 - 錯誤,因此您將獲得一些額外的文檔。如果有任何情況是可以接受的,那就結束了。

要考慮的另一件事是,只放一個限制,您將收到越來越多的文件,因爲在超過10分鐘的時間內會有越來越多的文件被更新。此外,您將一次又一次收到相同的文件。你應該考慮也放一個下限。

+0

謝謝,你可以請更新喜歡的票,這是解決方法,但我必須調用服務器兩次,並繼續同步手錶,我想設置最後更新時間測試和原子單一呼叫設置方法。 –