0

给定一个 mongo 集合(为了说明目的,仅精简到几个字段):

{
    "_id" : ObjectId("52402905e4b0cebf1e474093"),
    "impressionId" : LUUID("6a46028f-aa02-e87d-c097-01df765ec487"),
    "requestTime" : ISODate("2013-09-23T11:41:57.505Z"),
    "responseTime" : ISODate("2013-09-23T11:41:57.712Z"),
}

我想查询 requestTime。理想情况下,我想要两个查询,一个用于确切的 requestTime,一个用于一系列 requestTimes(大于或等于某个日期时间,小于或等于某个其他日期时间)。到目前为止,我已经尝试了以下方法,但似乎都没有奏效:

def fromDate = new Date(2013, 9, 22, 11, 41, 57)
def fromDateLong = fromDate.getTime()
def toDate = new Date(2013, 9, 23, 11, 41, 58);
def toDateLong = toDate.getTime()

// None of these return a record
def result = db.activityLog.find(requestTime : ['$date' : '2013-09-23T11:41:57.505Z']).count()
def result = db.activityLog.find(requestTime : ['$gte' : fromDateLong, '$lte' : toDateLong]).count()
def result = db.activityLog.find(requestTime : ["\\\$gte" : fromDateLong, "\\\$lte" : toDateLong]).count()
def result = db.activityLog.find(requestTime : ['$gte' : fromDate, '$lte' : toDate]).count()
def result = db.activityLog.find(requestTime : ["\\\$gte" : fromDate, "\\\$lte" : toDate]).count()

// I have also tried to read the first record form the mongo collection pull out the date (which works fine) and then query for this date (which doesn't work):

def result = db.activityLog.findOne()
println result.requestTime  // prints correct requestTime
def requestTimeLong = result.requestTime.getTime()
println requestTimeLong  // prints correct requestTime

def result2 = db.activityLog.find(requestTime : ["\\\$gte" : requestTimeLong]).count()
def result3 = db.activityLog.find(requestTime : ["\\\$date" : requestTimeLong]).count()
def result4 = db.activityLog.find(requestTime : ["\\\$gte" : result.requestTime]).count()
def result5 = db.activityLog.find(requestTime : ["\\\$date" : result.requestTime]).count()

println result2 // prints 0 for both above queries i.e. no records found
println result3 // prints 0 for both above queries i.e. no records found
println result4 // prints 0 for both above queries i.e. no records found
println result5 // prints 0 for both above queries i.e. no records found

有没有人有什么建议?对此的任何帮助将不胜感激。

我已经取得了一些进展,但还没有完全奏效。我可以检索记录并提取日期并在有效的查询中使用该日期。但是,如果我尝试自己创建日期,它将不起作用:

def result = db.activityLog.findOne(impressionId : ['$exists' : true])
def requestTimeResult = result.requestTime
println requestTimeResult
println requestTimeResult.class
def requestTimeLong = result.requestTime.getTime()
println requestTimeLong

def result2 = db.activityLog.find(requestTime: ['$gte': ['$date' : requestTimeLong]]).count()
def result3 = db.activityLog.find(requestTime: ['$gte': requestTimeResult]).count()

println result2
println result3

def fromDateNew = new Date(2013, 8, 23, 12, 41, 50)
println fromDateNew.class
println fromDateNew
def result4 = db.activityLog.find(requestTime: ['$gte': fromDateNew]).count()

println result4

输出:

Mon Sep 23 12:41:50 BST 2013
class java.util.Date
1379936510544
0
196869
class java.util.Date
Sat Aug 23 12:41:50 BST 3913
0
4

2 回答 2

2

You pretty much "always" want to do a "range query" when using dates. Unless you absolutely know the actual date value, which kind of defeats the point. So even for a single value like this:

"requestTime" : ISODate("2013-09-23T11:41:57.505Z"),

You really want to define a "small" range, possibly like:

db.activityLog.find({
    "requestTime": { 
        "$gte": new Date("2013-09-23 11:41:57"), 
        "$lt": new Date("2013-09-23 11:41:58")
    }
})

But in actual content of what you seem to be trying to do (and sort of illustrated above) what you need to do is use you "native" language platform implementation of a "date" type when passing into a query.

Dates in MongoDB are stored in a BSON representation which is actually an "epoch" timestamp internally. So your "native" dates are converted by the "driver" into this representation. The same is true when "reading" results from the collection, so the dates that MongoDB stores are converted to your "native" language date format.

So use the "native" way rather than converting to strings. The ISODate object type is just a mongo "shell" way of representing these "objects".

于 2014-03-28T11:36:54.810 回答
1

问题在于Date 构造函数。第一个参数不是年份本身,而是 1900 + 年。这就是为什么你在 2013 年之后得到 3913 的原因。更重要的是月份从 0 而不是 1 开始 - 这解释了为什么你得到的是八月而不是九月。

于 2014-03-28T12:27:21.237 回答