Ошибка при использовании параметра проекции gte с объектом ISODate в оболочке Mongodb

У меня есть коллекция с полем метки времени, хранящимся в формате ISODate. Эта база данных заполняется третьей стороной. Подмножество документа выглядит так:

collection{
    "_id" : "foobar/201310",
    "name" : "SomeName",
    "processedtime" : "2013-10-01T00:00:00.000Z",
    "value" : 375439
       .
       .
       .
}

Данные в поле processedtime выглядят как 2014-10-21T12:13:12.056790

Когда я запрашиваю эту коллекцию со следующим запросом:

db.collection.find({},{processedtime:{$gte : ISODate("2014-10-21T00:00:00.000Z")}});

Я получаю эту ошибку:

Неподдерживаемый параметр проекции "$gte", "code":13097";

Я получаю ту же ошибку, когда меняю ISODate в запросе на «новую дату» или меняю $gte на $gt

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


person Kirt Hall    schedule 23.10.2014    source источник
comment
Поправка, поле в моем запросе соответствует только микросекундам, некоторые другие поля в наборе данных соответствуют наносекундам, но не тому примеру, который я использовал здесь.   -  person Kirt Hall    schedule 23.10.2014
comment
Похоже, ваши даты хранятся в виде строк на основе вашего вывода, но из примера это не совсем ясно. Можете ли вы просто опубликовать вывод db.collection.findOne(), чтобы мы могли проверить фактическое содержимое полей?   -  person Adam Comerford    schedule 23.10.2014


Ответы (2)


db.collection.find({},{processedtime:{$gte : ISODate("2014-10-21T00:00:00.000Z")}}); должно быть db.collection.find({processedtime:{$gte : "2014-10-21T00:00:00.000Z"}});.

person Wizard    schedule 23.10.2014
comment
Когда я использую этот формат, я вообще не получаю результатов, хотя должны быть сотни коллекций, соответствующих критериям поиска. - person Kirt Hall; 23.10.2014
comment
@Kirt Hall, какой тип данных время обработки в базе данных, строка или дата? Если это Дата, используйте db.collection.find({processedtime:{$gte : ISODate("2014-10-21T00:00:00.000Z")}});. Но, судя по ответу на ваш вопрос, это тип String: "processedtime" : "2013-10-01T00:00:00.000Z", - person Wizard; 23.10.2014
comment
Я попробовал это снова, удалив конструктор ISODate, как указано в вашем ответе, и это сработало. Как указал Адам, данные хранятся не как объект ISODate, а как строка. Мне придется отсортировать лексикографический порядок в моем коде. Спасибо вам за ваши ответы! - person Kirt Hall; 23.10.2014

Во-первых, ваши критерии запроса (такие как $gte условия) входят в первый документ поиска, а не во второй, поэтому вы получаете ошибку проекции - вы говорите, что нужно вернуть все документы (пустое поле критериев - {}) и затем иметь по существу бессмысленную проекцию во втором поле. По сути, ваш запрос должен выглядеть так:

db.collection.find({processedtime:{$gte : ISODate("2014-10-21T00:00:00.000Z")}});

Если вы хотите вернуть только определенные поля, скажем, name и processedtime, вы должны добавить такую ​​проекцию. Теперь вы можете понять, почему исходный запрос не имел никакого смысла и выдавал ошибку:

db.collection.find({processedtime:{$gte : ISODate("2014-10-21T00:00:00.000Z")}}, {_id : 0, name : 1, processedtime : 1});

В вашем образце документа предполагается, что поле processedtime на самом деле хранится не как ISODate, а скорее как строка. Это означало бы, что ваш запрос должен быть:

db.collection.find({processedtime:{$gte : "2014-10-21T00:00:00.000Z"}});

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

Чтобы объяснить отсутствие результатов, тип строки стоит перед типом даты и времени UTC в спецификации BSON, что означает что если вы ищете строки «больше, чем» UTC datetime значений, вы всегда ничего не получите.

Кроме того, если у вас есть индекс processedtime и вы запускаете запрос для поиска определенного типа данных (ISODate), он будет возвращать результаты только этого типа. Следовательно, если processedtime действительно хранится в виде строки, то этот запрос также ничего не даст, независимо от используемых критериев из-за несоответствия типов.

person Adam Comerford    schedule 23.10.2014