Запрос даты Гмонго
Учитывая коллекцию монго (урезано до нескольких полей в иллюстративных целях):
{
"_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 и один для диапазона requestTimes (больше или равно некоторому datetime и меньше или равно некоторому другому datetime). До сих пор я пробовал следующее, но ни один из них не работает:
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
2 ответа
Проблема в конструкторе Date. Первый параметр - это не сам год, а 1900 год. Вот почему вы получаете 3913 при прохождении 2013 года. Более того, месяц начинается с 0, а не с 1 - это объясняет, почему вы получаете август вместо сентября.
Вы в значительной степени "всегда" хотите выполнить "запрос диапазона" при использовании дат. Если вы не знаете точно значение даты, которое побеждает точку. Так что даже для одного значения, как это:
"requestTime" : ISODate("2013-09-23T11:41:57.505Z"),
Вы действительно хотите определить "маленький" диапазон, например:
db.activityLog.find({
"requestTime": {
"$gte": new Date("2013-09-23 11:41:57"),
"$lt": new Date("2013-09-23 11:41:58")
}
})
Но в реальном контенте того, что вы, похоже, пытаетесь сделать (и вроде как показано выше), вам нужно использовать реализацию "родной" языковой платформы типа "дата" при передаче в запрос.
Даты в MongoDB хранятся в представлении BSON, которое фактически является внутренней меткой времени. Таким образом, ваши "родные" даты преобразуются "водителем" в это представление. То же самое верно, когда "чтение" происходит из коллекции, поэтому даты, которые хранит MongoDB, конвертируются в ваш формат даты "родного" языка.
Поэтому используйте "родной" способ, а не конвертируйте в строки. ISODate
Тип объекта - это просто монго-"оболочка" для представления этих "объектов".