Ошибка при использовании опции проекции gte с оболочкой ISODate objetc n Mongodb
У меня есть коллекция с полем timestamp, хранящимся в формате 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", "код":13097";
Я получаю ту же ошибку, когда меняю ISODate
в запросе "новая дата" или изменить $gte
в $gt
Я использую версию 2.4.6
, Есть ли какая-то часть конфигурации или синтаксическая проблема с моим запросом? Мне также интересно, так как данные выходят в нано секунды, это проблема? Я искал эту ошибку, и никто, кажется, не сообщает об этом с помощью такого запроса.
2 ответа
db.collection.find({},{processedtime:{$gte : ISODate("2014-10-21T00:00:00.000Z")}});
должно быть db.collection.find({processedtime:{$gte : "2014-10-21T00:00:00.000Z"}});
,
Прежде всего, ваши критерии запроса (такие как $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
действительно хранится в виде строки, то этот запрос также ничего не будет, независимо от используемых критериев из-за несоответствия типов.