所以我有一个集合存储事件的开始和结束时间,我希望用户能够通过指定“过滤器”开始和结束时间来查询事件。查询应返回与过滤时间相交的任何事件。我以为我正在构建查询,但它没有返回我想要的结果。
示例数据(获得想法的简化mongo文档,时间是HHMMSS):
{ ..., "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在应用查询的第二部分之前抛弃了与第一部分不匹配的结果,但我认为$或运算符会处理它。 有任何想法吗?我的查询不正确,这是在mongo中查询的限制吗?
答案 0 :(得分:4)
使用MongoDB 2.4.5我尝试了上述内容并在两种情况下都回到了“应该匹配”结果的前2位。
我不相信第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" }
>
答案 1 :(得分:1)
您的查询应该可以正常工作,但第三个不应匹配,因为start
和end
都不在范围内。
但是,您可以更清楚,更简洁地编写查询:
db.test.find({ $or: [
{ start: { $gte: "050600", $lt : "052000" }},
{ end: { $lt: "052000", $gt: "050600" }}
]});