Mongodb комплекс или / и запрос
Итак, у меня есть коллекции, в которых хранится время начала и окончания события, и я бы хотел, чтобы пользователь мог запрашивать события, указав время начала и окончания "фильтра". Запрос должен возвращать любые события, которые пересекаются со временем фильтрации. Я думал, что правильно строю запрос, но он не возвращает желаемых результатов.
Пример данных (упрощенный монго-документ, чтобы понять идею, времена - ЧЧММСС):
{ ..., "start" : "050520", "end" : "051309" } //Should match
{ ..., "start" : "051125", "end" : "051925" } //Should match
{ ..., "start" : "052049", "end" : "052420" } //Should match
{ ..., "start" : "050000", "end" : "050500" }
{ ..., "start" : "052100", "end" : "052721" }
Запрос, который я пробовал, был (простите, если я пропустил скобку здесь, это не проблема):
find( { $or : [
{ start : { $gte : "050600", $lt : "052100" } },
{ end : { $lt : "052100", $gt : "050600" } }
] } )
Который вернул только один из трех результатов. Переключение порядка $ или частей (запрос времени окончания до времени начала) дает мне два результата, но не все три. Кажется, я помню, что читал, что для составных запросов Mongo выбрасывает результаты, которые не соответствуют первой части, перед применением второй части запроса, но я думал, что оператор $ или справится с этим. Есть идеи? Является ли мой запрос неверным, это ограничение запросов в монго?
2 ответа
Используя MongoDB 2.4.5, я попробовал вышеизложенное и в обоих случаях получил первые два из ваших результатов "должны соответствовать".
Я не верю, что 3-е должно быть возвращено так, как этого требует ("052049" >= "050600" && "052049" <"052000") или ("052420" <"052000" && "052420"> "050600") ни один из которых не соответствует действительности.
MongoDB shell version: 2.4.5
connecting to: test
>
> db.mycol.save({ "start" : "050520", "end" : "051309" })
> db.mycol.save({ "start" : "051125", "end" : "051925" })
> db.mycol.save({ "start" : "052049", "end" : "052420" })
> db.mycol.save({ "start" : "050000", "end" : "050500" })
> db.mycol.save({ "start" : "052100", "end" : "052721" })
>
> db.mycol.find(
... { $or :
... [ { $and : [ { start : { $gte : "050600" } }, { start : { $lt : "052000" } } ] },
... { $and : [ { end : { $lt : "052000" } }, { end : { $gt : "050600" } } ] }
... ]
... } )
{ "_id" : ObjectId("520528522683a40682f12b5c"), "start" : "050520", "end" : "051309" }
{ "_id" : ObjectId("520528522683a40682f12b5d"), "start" : "051125", "end" : "051925" }
>
>
> db.mycol.find(
... { $or :
... [ { $and : [ { end : { $lt : "052000" } }, { end : { $gt : "050600" } } ] } ,
... { $and : [ { start : { $gte : "050600" } }, { start : { $lt : "052000" } } ] }
... ]
... } )
{ "_id" : ObjectId("520528522683a40682f12b5c"), "start" : "050520", "end" : "051309" }
{ "_id" : ObjectId("520528522683a40682f12b5d"), "start" : "051125", "end" : "051925" }
>
Ваш запрос должен работать нормально, но третий не должен совпадать, так как оба start
а также end
вне диапазона.
Тем не менее, вы можете написать свой запрос более четко и кратко, как:
db.test.find({ $or: [
{ start: { $gte: "050600", $lt : "052000" }},
{ end: { $lt: "052000", $gt: "050600" }}
]});