Поиск объектов между двумя датами MongoDB

Я играл вокруг хранения твитов внутри 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
}

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

10 ответов


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

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" }

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


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

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

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

var inputDate = new Date(myDate.toISOString());
MyModel.find({
    'date': { $lte: inputDate }
})

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

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

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


db.collection.find({"createdDate":{$gte:new ISODate("2017-04-14T23:59:59Z"),$lte:new ISODate("2017-04-15T23:59:59Z")}}).count();

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


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 типы.


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

db.CollectionName.find({"whenCreated": {
    '$gte': ISODate("2018-03-06T13:10:40.294Z"),
    '$lt': ISODate("2018-05-06T13:10:40.294Z")
}});

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


Почему бы не преобразовать строку в целое число вида YYYYMMDDHHMMSS? Каждое приращение времени создаст большее целое число, и вы можете фильтровать целые числа вместо того, чтобы беспокоиться о преобразовании в ISO-время.


Я попытался в этой модели в соответствии с моими требованиями мне нужно сохранить дату, когда когда-либо объект будет создан позже я хочу получить все записи (документы ) между двумя датами в моем html-файле я использовал следующий формат mm/dd / yyyy

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>

    <script>
//jquery
    $(document).ready(function(){  
    $("#select_date").click(function() { 
    $.ajax({
    type: "post",
    url: "xxx", 
    datatype: "html",
    data: $("#period").serialize(),  
    success: function(data){
    alert(data);
    } ,//success

    }); //event triggered

    });//ajax
    });//jquery  
    </script>

    <title></title>
</head>

<body>
    <form id="period" name='period'>
        from <input id="selecteddate" name="selecteddate1" type="text"> to 
        <input id="select_date" type="button" value="selected">
    </form>
</body>
</html>

в моем файле py (python) я конвертировал его в " iso fomate" следующим образом

date_str1   = request.POST["SelectedDate1"] 
SelectedDate1   = datetime.datetime.strptime(date_str1, '%m/%d/%Y').isoformat()

и сохранен в моей коллекции dbmongo с полем" SelectedDate " в моей коллекции

для получения данных или документов между двумя датами я использовал следующий запрос

db.collection.find( "SelectedDate": {'$gte': SelectedDate1,'$lt': SelectedDate2}})

использовать $get и $lt чтобы найти между данными даты в 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"),$lt: new Date(tomorrowDate + "T23:59:59.999Z")}})