MongoDB查询日期字段,服务器时间为

时间:2017-07-14 12:21:03

标签: node.js mongodb node-mongodb-native mongojs

我有mongo文档,其中包含使用$ currentDate插入日期的字段,因此当我插入文档时,该字段具有mongo服务器日期。 我想查询并过滤所有文档,日期字段和服务器日期之间的差异超过10分钟。

假设这个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:10:01Z”服务器日期运行查询, 我希望查询只返回第一个项目。

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

如何在运行查询时获取服务器日期?  我从我的nodeJS服务器运行查询,用新的Date()替换服务器日期将得到节点服务器的日期而不是mongo服务器。

2 个答案:

答案 0 :(得分:3)

这比初看起来更棘手。当涉及复制和分片时,很难保证所有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分钟的时间内会有越来越多的文档被更新。此外,您将一遍又一遍地收到相同的文件。你应该考虑下限。

答案 1 :(得分:0)

mongodb服务器允许使用 $ currentDate 运算符更新字段,但我没有找到任何在查询过滤器中使用日期的选项。

但可以选择使用“在服务器上存储JavaScript函数”https://docs.mongodb.com/manual/tutorial/store-javascript-function-on-server/  并添加一个将返回日期的函数。