Dit is echt een verwarrend onderwerp. Ik werk bij 10gen en ik moest er even mijn hoofd omheen draaien;)
Laten we eens kijken hoe de query-engine deze query verwerkt.
Hier is de vraag opnieuw:
> db.test.find({ b : { $gt : 4, $lt : 6}});
Als het bij het record komt dat lijkt alsof het niet zou moeten overeenkomen...
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] }
De match wordt niet uitgevoerd tegen elk element van de array, maar tegen de array als geheel.
De vergelijking wordt in drie stappen uitgevoerd:
Stap 1 :Vind alle documenten waar b een waarde groter dan 4 heeft
b:[2,4,6,8] komt overeen omdat 6 &8 groter zijn dan 4
Stap 2 :Vind alle documenten waar b een waarde kleiner dan 6 heeft
b:[2,4,6,8] komt overeen omdat 2 &4 kleiner zijn dan 6
Stap 3 :Zoek de set documenten die overeenkwamen in zowel stap 1 als 2.
Het document met b:[2,4,6,8] kwam overeen met beide stappen 1 &2, dus het wordt geretourneerd als een overeenkomst. Houd er rekening mee dat de resultaten in deze stap ook worden gededupliceerd, zodat hetzelfde document niet twee keer wordt geretourneerd.
Als u wilt dat uw query van toepassing is op de afzonderlijke elementen van de array, in plaats van op de array als geheel, kunt u de operator $elemMatch gebruiken. Bijvoorbeeld
> 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 ] }