Найти объекты между двумя датами MongoDB - PullRequest
340 голосов
/ 31 мая 2010

Я играл в хранилище твитов внутри mongodb, каждый объект выглядит так:

{
"_id" : ObjectId("4c02c58de500fe1be1000005"),
"contributors" : null,
"text" : "Hello world",
"user" : {
    "following" : null,
    "followers_count" : 5,
    "utc_offset" : null,
    "location" : "",
    "profile_text_color" : "000000",
    "friends_count" : 11,
    "profile_link_color" : "0000ff",
    "verified" : false,
    "protected" : false,
    "url" : null,
    "contributors_enabled" : false,
    "created_at" : "Sun May 30 18:47:06 +0000 2010",
    "geo_enabled" : false,
    "profile_sidebar_border_color" : "87bc44",
    "statuses_count" : 13,
    "favourites_count" : 0,
    "description" : "",
    "notifications" : null,
    "profile_background_tile" : false,
    "lang" : "en",
    "id" : 149978111,
    "time_zone" : null,
    "profile_sidebar_fill_color" : "e0ff92"
},
"geo" : null,
"coordinates" : null,
"in_reply_to_user_id" : 149183152,
"place" : null,
"created_at" : "Sun May 30 20:07:35 +0000 2010",
"source" : "web",
"in_reply_to_status_id" : {
    "floatApprox" : 15061797850
},
"truncated" : false,
"favorited" : false,
"id" : {
    "floatApprox" : 15061838001
}

Как мне написать запрос, который проверяет made_at и находит все объекты в период с 18:47 до 19:00? Нужно ли обновлять документы, чтобы даты сохранялись в определенном формате?

Ответы [ 11 ]

524 голосов
/ 31 мая 2010

Запрос диапазона дат (определенный месяц или день) в MongoDB Cookbook содержит очень хорошее объяснение по этому вопросу , но ниже я кое-что попробовал сам, и, похоже, работает.

items.save({
    name: "example",
    created_at: ISODate("2010-04-30T00:00:00.000Z")
})
items.find({
    created_at: {
        $gte: ISODate("2010-04-29T00:00:00.000Z"),
        $lt: ISODate("2010-05-01T00:00:00.000Z")
    }
})
=> { "_id" : ObjectId("4c0791e2b9ec877893f3363b"), "name" : "example", "created_at" : "Sun May 30 2010 00:00:00 GMT+0300 (EEST)" }

На основании моих экспериментов вам нужно будет сериализовать ваши даты в формат, который поддерживает MongoDB, потому что следующее дало нежелательные результаты поиска.

items.save({
    name: "example",
    created_at: "Sun May 30 18.49:00 +0000 2010"
})
items.find({
    created_at: {
        $gte:"Mon May 30 18:47:00 +0000 2015",
        $lt: "Sun May 30 20:40:36 +0000 2010"
    }
})
=> { "_id" : ObjectId("4c079123b9ec877893f33638"), "name" : "example", "created_at" : "Sun May 30 18.49:00 +0000 2010" }

Во втором примере никаких результатов не ожидалось, но был еще один полученный. Это потому, что основное сравнение строк сделано.

27 голосов
/ 30 июля 2014

Чтобы уточнить.Важно знать, что:

  • Да, вы должны передать объект Javascript Date.
  • Да, он должен быть дружественным к ISODate
  • Да, исходя из моего опыта, чтобы это работало, вам нужно манипулировать датой с ISO
  • Да, работа с датамикак правило, это всегда утомительный процесс, и mongo не является исключением

Вот рабочий фрагмент кода, в котором мы немного манипулируем датой для обеспечения Mongo (здесь я использую модуль mongoose и хочу получить результатыдля строк, у которых атрибут даты меньше (до) даты, указанной в параметре myDate), может обработать ее правильно:

var inputDate = new Date(myDate.toISOString());
MyModel.find({
    'date': { $lte: inputDate }
})
16 голосов
/ 04 июня 2010

MongoDB фактически хранит миллис даты как целое число (64), как предписано http://bsonspec.org/#/specification

Однако, это может привести к путанице при получении дат, поскольку драйвер клиента будет создавать экземпляр объекта даты со своим собственным локальным часовым поясом. Драйвер JavaScript в консоли Монго, безусловно, сделает это.

Итак, если вы заботитесь о своих часовых поясах, убедитесь, что вы знаете, что это должно быть, когда получите его обратно. Это не должно иметь большого значения для запросов, так как все равно будет равняться тому же самому int (64), независимо от того, в каком часовом поясе находится ваш объект даты (я надеюсь). Но я бы определенно делал запросы с фактическими объектами даты (не строками) и позволял бы драйверу делать свое дело.

10 голосов
/ 26 апреля 2017
db.collection.find({"createdDate":{$gte:new ISODate("2017-04-14T23:59:59Z"),$lte:new ISODate("2017-04-15T23:59:59Z")}}).count();

Заменить collection именем коллекции, для которой вы хотите выполнить запрос

9 голосов
/ 16 января 2018

Python и pymongo

Поиск объектов между двумя датами в Python с pymongo в коллекции posts (на основе учебника ):

from_date = datetime.datetime(2010, 12, 31, 12, 30, 30, 125000)
to_date = datetime.datetime(2011, 12, 31, 12, 30, 30, 125000)

for post in posts.find({"date": {"$gte": from_date, "$lt": to_date}}):
    print(post)

Где {"$gte": from_date, "$lt": to_date} указывает диапазон в виде datetime.datetime типов.

5 голосов
/ 17 мая 2018

Используйте этот код, чтобы найти запись между двумя датами, используя $gte и $lt:

db.CollectionName.find({"whenCreated": {
    '$gte': ISODate("2018-03-06T13:10:40.294Z"),
    '$lt': ISODate("2018-05-06T13:10:40.294Z")
}});
2 голосов
/ 05 декабря 2018

Использование с Moment.js и Операторы запросов сравнения

  var today = moment().startOf('day');
  // "2018-12-05T00:00:00.00
  var tomorrow = moment(today).endOf('day');
  // ("2018-12-05T23:59:59.999

  Example.find(
  {
    // find in today
    created: { '$gte': today, '$lte': tomorrow }
    // Or greater than 5 days
    // created: { $lt: moment().add(-5, 'days') },
  }), function (err, docs) { ... });
2 голосов
/ 09 июня 2015

Почему бы не преобразовать строку в целое число вида ГГГГММДДЧЧММСС? Затем каждый прирост времени будет создавать большее целое число, и вы сможете фильтровать целые числа, не беспокоясь о преобразовании во время ISO.

2 голосов
/ 16 января 2014

Конвертируйте ваши даты в часовой пояс GMT, когда вы вводите их в Mongo. Таким образом, никогда не бывает проблем с часовыми поясами. Затем просто сделайте математику в поле твиттера / часового пояса, когда вы извлекаете данные обратно для представления.

1 голос
/ 07 декабря 2017

используйте $ gte и $ lte , чтобы найти данные о дате в mongodb

var tomorrowDate = moment(new Date()).add(1, 'days').format("YYYY-MM-DD");
db.collection.find({"plannedDeliveryDate":{ $gte: new Date(tomorrowDate +"T00:00:00.000Z"),$lte: new Date(tomorrowDate + "T23:59:59.999Z")}})
...