Dette er et virkelig forvirrende emne. Jeg arbejder på 10gen, og jeg var nødt til at bruge et stykke tid på at vikle hovedet om det;)
Lad os gennemgå, hvordan forespørgselsmotoren behandler denne forespørgsel.
Her er forespørgslen igen:
> db.test.find({ b : { $gt : 4, $lt : 6}});
Når det kommer til posten, der ser ud til, at den ikke burde matche...
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] }
Matchningen udføres ikke mod hvert element i arrayet, men snarere mod arrayet som helhed.
Sammenligningen udføres i tre trin:
Trin 1 :Find alle dokumenter, hvor b har en værdi større end 4
b:[2,4,6,8] matcher, fordi 6 og 8 er større end 4
Trin 2 :Find alle dokumenter, hvor b har en værdi mindre end 6
b:[2,4,6,8] matcher, fordi 2 og 4 er mindre end 6
Trin 3 :Find det sæt af dokumenter, der matchede i både trin 1 og 2.
Dokumentet med b:[2,4,6,8] matchede begge trin 1 og 2, så det returneres som et match. Bemærk, at resultater også de-duplikeres i dette trin, så det samme dokument vil ikke blive returneret to gange.
Hvis du ønsker, at din forespørgsel skal gælde for de individuelle elementer i arrayet i stedet for arrayet som helhed, kan du bruge $elemMatch-operatoren. For eksempel
> 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 ] }