Запрос даты с ISODate в mongodb, похоже, не работает

Кажется, я не могу заставить работать в MongoDB даже самый простой запрос даты. С документом, который выглядит примерно так:

{
    "_id" : "foobar/201310",
    "ap" : "foobar",
    "dt" : ISODate("2013-10-01T00:00:00.000Z"),
    "tl" : 375439
}

И запрос, который выглядит так:

{ 
    "dt" : { 
        "$gte" : { 
            "$date" : "2013-10-01T00:00:00.000Z"
        }
    }
}

Я получаю 0 результатов при выполнении:

db.mycollection.find({
  "dt" : { "$gte" : { "$date" : "2013-10-01T00:00:00.000Z"}}
})

Есть идеи, почему это не работает?

Для справки: этот запрос создается MongoTemplate Spring, поэтому у меня нет прямого контроль над запросом, который в конечном итоге отправляется в MongoDB.

(P.S.)

> db.version()
2.4.7

Спасибо!


person Jason Polites    schedule 06.11.2013    source источник


Ответы (10)


Хотя $date является частью MongoDB Extended JSON, и это то, что вы получаете по умолчанию с mongoexport Я не думаю, что вы действительно можете использовать его как часть запроса.

Если попробовать точный поиск с $date, как показано ниже:

db.foo.find({dt: {"$date": "2012-01-01T15:00:00.000Z"}})

вы получите ошибку:

error: { "$err" : "invalid operator: $date", "code" : 10068 }

Попробуй это:

db.mycollection.find({
    "dt" : {"$gte": new Date("2013-10-01T00:00:00.000Z")}
})

или (после комментариев @ user3805045):

db.mycollection.find({
    "dt" : {"$gte": ISODate("2013-10-01T00:00:00.000Z")}
})

ISODate может также потребоваться для сравнения дат без учета времени (отмечено @MattMolnar).

Согласно типам данных в оболочке mongo оба должны быть эквивалентными:

Оболочка mongo предоставляет различные методы для возврата даты в виде строки или объекта Date:

  • Date (), который возвращает текущую дату в виде строки.
  • конструктор new Date (), который возвращает объект Date с помощью оболочки ISODate ().
  • Конструктор ISODate (), который возвращает объект Date с помощью оболочки ISODate ().

и использование ISODate по-прежнему должно возвращать объект Date < / а>.

{"$date": "ISO-8601 string"} можно использовать, когда требуется строгое представление JSON. Один из возможных примеров - коннектор Hadoop.

person zero323    schedule 06.11.2013
comment
При сравнении частичной (без времени) даты мне пришлось переключиться с new Date('2016-03-09') на ISODate('2016-03-09'). Первый будет возвращать даты в прошлом для $gte запроса. - person Matt Molnar; 09.03.2016
comment
@MattMolnar Отметил и обновил ответ с указанием авторства. Спасибо. - person zero323; 09.03.2016

Из комментариев страницы книги рецептов MongoDB :

"dt" : 
{
    "$gte" : ISODate("2014-07-02T00:00:00Z"), 
    "$lt" : ISODate("2014-07-03T00:00:00Z") 
}

Это сработало для меня. В полном контексте следующая команда получает каждую запись, в которой поле даты dt имеет дату на 2013-10-01 (ГГГГ-ММ-ДД) зулусский язык:

db.mycollection.find({ "dt" : { "$gte" : ISODate("2013-10-01T00:00:00Z"), "$lt" : ISODate("2013-10-02T00:00:00Z") }})
person Steve HHH    schedule 02.07.2014
comment
Я получил неопределенную ошибку ISODate. Я не мог решить эту проблему. - person Batu; 02.02.2019
comment
@BatuhanAkkaya В python с pymongo datetime.datetime эквивалентно ISODate. - person jtbr; 12.03.2019

Попробуй это:

{ "dt" : { "$gte" : ISODate("2013-10-01") } }
person Jabba    schedule 18.01.2016

Я использую robomongo в качестве графического интерфейса клиента mongodb, и приведенное ниже сработало для меня

db.collectionName.find({"columnWithDateTime" : {
$lt:new ISODate("2016-02-28T00:00:00.000Z")}})

На стороне приложения я использую драйвер mongodb на основе nodejs (v1.4.3), приложение использует datepicker в пользовательском интерфейсе, который дает дату, например, YYYY-mm-dd, затем добавляется время по умолчанию, например 00:00:00, а затем дается в конструктор new Date(), а затем передается объекту критериев mongodb, я думаю, что драйвер преобразует дату в дату ISO, и запрос затем работает и дает желаемый результат, однако тот же конструктор new Date() не работает или не показывает тот же результат на robo mongo, для те же критерии, что странно, поскольку я использовал robomongo для перекрестной проверки моих объектов критериев.

В то время как cli mongoshell по умолчанию хорошо работает как с ISODate, так и с new Date()

person siddharthrc    schedule 11.02.2016
comment
Спасибо за подсказку, Robomongo намного лучше, чем Mongo Compass - person Alex; 04.07.2017

В строгом режиме json вам нужно будет соблюдать порядок:

{
    "dt": {
        "$gte": {
            "$date": "2013-10-01T00:00:00.000Z"
        }
    }
}

Единственное, что помогло мне определить мои поисковые запросы на mlab.com.

person 3vangelos    schedule 24.10.2016
comment
Ошибка выполнения запроса. Причина: (invalid_operator) Недействительный оператор: $ date - person saber tabatabaee yazdi; 13.09.2018

это мой документ

"_id" : ObjectId("590173023c488e9a48e903d6"),
    "updatedAt" : ISODate("2017-04-27T04:26:42.709Z"),
    "createdAt" : ISODate("2017-04-27T04:26:42.709Z"),
    "flightId" : "590170f97cb84116075e2680",

 "_id" : ObjectId("590173023c488e9a48e903d6"),
        "updatedAt" : ISODate("2017-04-28T03:26:42.609Z"),
        "createdAt" : ISODate("2017-04-28T03:26:42.609Z"),
        "flightId" : "590170f97cb84116075e2680",

теперь я хочу найти каждый документ 27-й даты. поэтому я использовал это ....

 > db.users.find({createdAt:{"$gte":ISODate("2017-04-27T00:00:00Z"),"$lt":ISODate("2017-04-28T00:00:00Z") }}).count()

result:1

это сработало для меня.

person coder    schedule 01.05.2017

В оболочке MongoDB:

db.getCollection('sensorevents').find({from:{$gt: new ISODate('2015-08-30 16:50:24.481Z')}})

В моем коде nodeJS (с использованием Mongoose)

    SensorEvent.Model.find( {
        from: { $gt: new Date( SensorEventListener.lastSeenSensorFrom ) }
    } )

Я запрашиваю свою коллекцию событий датчика, чтобы вернуть значения, в которых поле «от» больше заданной даты.

person lewma    schedule 30.08.2015
comment
Добро пожаловать в Stack Overflow! Пожалуйста, просто отправьте ответ на вопрос, а не лишние вещи вроде Это мой первый пост. Думайте о Stack Overflow как о Википедии, а не как о доске объявлений. - person durron597; 30.08.2015

Оберните его new Date():

{ "dt" : { "$lt" : new Date("2012-01-01T15:00:00.000Z") } }
person TheEhsanSarshar    schedule 17.05.2020

Старый вопрос, но все же первый хит Google, поэтому я размещаю его здесь, чтобы мне было легче найти его снова ...

Используя Mongo 4.2 и агрегат ():

db.collection.aggregate(
    [
     { $match: { "end_time": { "$gt": ISODate("2020-01-01T00:00:00.000Z")  } } },
     { $project: {
          "end_day": { $dateFromParts: { 'year' : {$year:"$end_time"}, 'month' : {$month:"$end_time"}, 'day': {$dayOfMonth:"$end_time"}, 'hour' : 0  } }
     }}, 
     {$group:{
        _id:   "$end_day",
        "count":{$sum:1},
    }}
   ]
)

Это дает вам переменную groupby в качестве даты, иногда лучше обрабатывать как сами компоненты.

person A. Rabus    schedule 03.06.2020

Это сработало для меня при поиске значения, меньшего или равного, чем сейчас:

db.collectionName.find({ "dt": { "$lte" : new Date() + "" } });
person JulienRioux    schedule 13.11.2019