Това е наистина объркваща тема. Аз работя на 10gen и трябваше да прекарам известно време, за да си въртя главата около него;)
Нека да преминем през това как машината за заявки обработва тази заявка.
Ето отново заявката:
> db.test.find({ b : { $gt : 4, $lt : 6}});
Когато стигне до записа, изглежда, че не трябва да съвпада...
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] }
Съвпадението не се извършва срещу всеки елемент от масива, а по-скоро срещу масива като цяло.
Сравнението се извършва в три стъпки:
Стъпка 1 :Намерете всички документи, където b има стойност по-голяма от 4
b:[2,4,6,8] съвпада, защото 6 и 8 са по-големи от 4
Стъпка 2 :Намерете всички документи, където b има стойност по-малка от 6
b:[2,4,6,8] съвпада, защото 2 и 4 са по-малко от 6
Стъпка 3 :Намерете набора от документи, които съвпадат както в стъпка 1, така и в стъпка 2.
Документът с b:[2,4,6,8] съответства на двете стъпки 1 и 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 ] }