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" }}
]});
Другие вопросы по тегам