ケース 1: 配列値に対する範囲クエリ
編集:間違った値を使用してテストを行いました。
ドキュメントで説明されているように、配列値に対して条件演算子 (AND 暗黙演算子) を使用すると、ドキュメントを返すために 1 つの条件に一致するだけで済みます。
そう、
- _id:1 は $lte 句と $gte 句に一致: OK
- _id:2 は $lte 句と $gte 句に一致: OK
- _id:3 は $lte (5 < 10 and 1 < 10) 句のみに一致します: OK ではありませんが、ドキュメントで説明されているように意図したとおりに機能します。
この範囲クエリを使用して配列値をフィルタリングする必要がある場合は、次のように、オブジェクトを使用して値をラップする必要があります。
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}]}
このクエリにインデックスを使用する場合は、次のようにします。
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,
...
}
ケース 2: オープン レンジを使用してインデックスにヒットする
ご覧のとおり、このクエリは期待どおりにインデックスにヒットします。
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"
}