これは本当に紛らわしいトピックです。私は10genで働いており、頭を包み込むのにしばらく時間を費やす必要がありました;)
クエリエンジンがこのクエリを処理する方法を見ていきましょう。
もう一度クエリを示します:
> db.test.find({ b : { $gt : 4, $lt : 6}});
一致してはいけないように見えるレコードに到達したら...
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] }
一致は、配列の各要素に対して実行されるのではなく、配列全体に対して実行されます。
比較は次の3つのステップで実行されます。
ステップ1 :bの値が4より大きいすべてのドキュメントを検索します
b:6と8が4より大きいため、[2,4,6,8]が一致します
ステップ2 :bの値が6未満のすべてのドキュメントを検索する
b:2と4が6未満であるため、[2,4,6,8]が一致します
ステップ3 :手順1と2の両方で一致したドキュメントのセットを検索します。
b:[2,4,6,8]のドキュメントは、ステップ1と2の両方に一致したため、一致として返されます。このステップでは結果も重複排除されるため、同じドキュメントが2回返されることはありません。
配列全体ではなく、配列の個々の要素にクエリを適用する場合は、$elemMatch演算子を使用できます。例
> db.temp.find({b: {$elemMatch: {$gt: 4, $lt: 5}}})
> db.temp.find({b: {$elemMatch: {$gte: 4, $lt: 5}}})
{ "_id" : ObjectId("4d558b6f4f0b1e2141b66660"), "b" : [ 2, 3, 4, 5, 6 ] }