第一。
我们在db中有以下记录
{ _id:1, values: [ 1 ,5 ,6 ,8]},
{ _id:2, values: [5 ,7 ,8,10 ,40 ,1]},
{ _id:3, values: [50 ,60 ,5 ,1 ]}
Run Code Online (Sandbox Code Playgroud)
我需要查询所有记录,其中包含范围8-10的“值”。 {_id:1},{_id:2}
query ({values:{'$gte':8,'$lte':10}}) 返回所有记录,由于“值”为数组,因此结果不正确!
第二。
我们在db中有以下记录
{_id:1, from: 1, to:100},
{_id:2, from: 101, to:200},
{_id:3, from: 201, to:300},
{_id:4, from: 301, to:400} ...
Run Code Online (Sandbox Code Playgroud)
我需要找到元素205在从到范围内的记录。结果{_id:3}
query({from:{'$lte':205},to:{'$gte':205})
Run Code Online (Sandbox Code Playgroud)
非常慢,根本不使用任何索引{from:1,to:1};
我有点困惑。有人可以帮忙吗?
谢谢。
编辑:我使用错误的值进行了测试。
正如文档所解释的,在数组值上使用条件运算符(AND 隐式运算符),只需要匹配一个条件即可返回文档。
所以,
如果您需要使用此范围查询对数组值进行过滤,则必须使用对象包装这些值,如下所示:
db.test_col2.insert({values:[{v:1} ,{v:5 },{v:6} ,{v:8}]})
db.test_col2.insert({values:[{v:5 },{v:7} ,{v:8},{v:10 },{v:40} ,{v:1}]})
db.test_col2.insert({values: [{v:50} ,{v:60} ,{v:5} ,{v:1} ]})
db.test_col2.find({values: {$elemMatch:{v:{$lte:10, $gte:8}}} })
{"_id":ObjectId("51273098140d09d9105739b5"),"values":[{"v":1},{"v":5},{"v":6},{"v":8}]}
{"_id":ObjectId("51273098140d09d9105739b6"),"values":[{"v":5},{"v":7},{"v":8},{"v":10},{"v":40},{"v":1}]}
Run Code Online (Sandbox Code Playgroud)
如果你想在这个查询中使用索引,你可以这样做:
db.test_col2.ensureIndex({"values.v":1})
db.test_col2.find({values: {$elemMatch:{v:{$lte:10, $gte:8}}} }).explain()
{
"cursor": "BtreeCursor values.v_1",
"isMultiKey": true,
...
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,该查询按预期命中了索引。
for(var i=0 ; i<120000 ; i++) {
... db.test_col.insert({from: (Math.random()*100)%100, to: (Math.random()*100)%100});
... }
> db.test_col.ensureIndex({from:1, to:1})
> db.test_col.count()
120002
> db.test_col.find({from:{$gte:3}, to:{$lt:60}}).explain()
{
"cursor" : "BtreeCursor from_1_to_1",
"isMultiKey" : false,
"n" : 69741,
"nscannedObjects" : 69902,
"nscanned" : 116563,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 340,
"indexBounds" : {
"from" : [
[
3,
1.7976931348623157e+308
]
],
"to" : [
[
-1.7976931348623157e+308,
60
]
]
},
"server" : "new-host-2.home:27017"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2554 次 |
| 最近记录: |