Mongoid запрос диапазона дат - PullRequest
14 голосов
/ 06 мая 2011

Я не могу найти ничего, чтобы сделать запрос диапазона дат, используя Mongoid / Rails.Ниже приведены некоторые запросы, которые я пробовал (около 100 других).Если он что-то возвращает, он всегда игнорирует end_date.Обе даты являются datetime ...

all(:conditions => {:created_at => start_date.to_datetime..end_date.to_datetime})

результаты:

NoMethodError: undefined method `to_i' for Tue, 26 Apr 2011 00:00:00 +0000..Fri, 06 May 2011 00:00:00 +0000:Range

другой пример ...

where(:created_at => {'$gte' => start_date,'$lt' => end_date})

приводит к успешному запросу, но конецдата игнорируется.Результаты возвращаются правильно после даты начала, но не ограничены датой окончания.

Я работал над этой проблемой в течение нескольких дней, но безрезультатно.Не сильно поможет онлайн, на форумах или IRC.

Хотелось бы понять, что я делаю не так:)

Ответы [ 3 ]

11 голосов
/ 07 мая 2011

В Mongoid была ошибка.Исправлено.

Для получения дополнительной информации:

https://github.com/mongoid/mongoid/issues/761

https://github.com/mongoid/mongoid/commit/f326de5acc969e1342e640dc026de7e94bf4cf49#lib/mongoid/matchers.rb

2 голосов
/ 06 мая 2011

Я провел небольшое исследование и наткнулся на сообщение Расширенные запросы , в котором один пользователь спрашивает:

Есть ли лучший способ сортировки или запроса используя сравнение даты и времени, чем хранить дату в Монго как целое число секунд с эпохи? это в настоящее время единственный способ, который работает для меня, чтобы сделать сравнения Gte в Монго для получения результатов.

Ответ другого пользователя на это:

Использовать собственный тип даты BSON. Внутренне это 64-битное целое число количество миллисекунд с эпоха.

Так что вы, возможно, захотите подойти к этому по-другому и конвертировать количество миллисекунд с начала эпохи для ваших запросов диапазона. Таким образом, вы делаете простой gte/lt на целых числах. Предложение пользователя является относительно новым (опубликовано 3 месяца назад), поэтому оно все еще может быть наиболее надежным способом сравнения дат с Mongo в целом (и, следовательно, с Mongoid).

0 голосов
/ 06 мая 2011

Я использовал оболочку MongoDB для проверки этого:

Выполнено несколько раз

db.con.save ({создано: новая дата ()})

Тогда я получил

> db.con.find()
{ "_id" : ObjectId("4dc3d380724a42d80d636b09"), "created" : ISODate("2011-05-06T10:54:56.809Z") }
{ "_id" : ObjectId("4dc3d383724a42d80d636b0a"), "created" : ISODate("2011-05-06T10:54:59.699Z") }
{ "_id" : ObjectId("4dc3d385724a42d80d636b0b"), "created" : ISODate("2011-05-06T10:55:01.543Z") }
{ "_id" : ObjectId("4dc3d38b724a42d80d636b0c"), "created" : ISODate("2011-05-06T10:55:07.043Z") }
{ "_id" : ObjectId("4dc3d38c724a42d80d636b0d"), "created" : ISODate("2011-05-06T10:55:08.168Z") }
{ "_id" : ObjectId("4dc3d49d4087861731076f8a"), "created" : ISODate("2011-05-06T10:59:41.755Z") }

В качестве даты разделения я выбираю ISODate("2011-05-06T10:55:00Z"), создайте ее с помощью d = new Date(2011,04,06,12,55,00) Различия происходят, поскольку месяц начинается с нуля, а время - это часовой пояс. Теперь db.con.find({"created": {$gt:d}}) дает

{ "_id" : ObjectId("4dc3d385724a42d80d636b0b"), "created" : ISODate("2011-05-06T10:55:01.543Z") }
{ "_id" : ObjectId("4dc3d38b724a42d80d636b0c"), "created" : ISODate("2011-05-06T10:55:07.043Z") }
{ "_id" : ObjectId("4dc3d38c724a42d80d636b0d"), "created" : ISODate("2011-05-06T10:55:08.168Z") }
{ "_id" : ObjectId("4dc3d49d4087861731076f8a"), "created" : ISODate("2011-05-06T10:59:41.755Z") }

Итак, MongoDb все делает правильно. Как это сделать в Ruby, я не знаю.

...