C'est un sujet vraiment déroutant. Je travaille chez 10gen et j'ai dû passer un moment à m'y mettre;)
Voyons comment le moteur de requête traite cette requête.
Voici à nouveau la requête :
> db.test.find({ b : { $gt : 4, $lt : 6}});
Quand il arrive à l'enregistrement qui semble ne pas correspondre...
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] }
La correspondance n'est pas effectuée sur chaque élément du tableau, mais plutôt sur le tableau dans son ensemble.
La comparaison s'effectue en trois étapes :
Étape 1 :Trouve tous les documents où b a une valeur supérieure à 4
b :[2,4,6,8] correspond car 6 et 8 sont supérieurs à 4
Étape 2 :Trouve tous les documents où b a une valeur inférieure à 6
b :[2,4,6,8] correspond car 2 et 4 sont inférieurs à 6
Étape 3 :recherchez l'ensemble de documents correspondant aux étapes 1 et 2.
Le document avec b :[2,4,6,8] correspondait aux deux étapes 1 et 2, il est donc renvoyé comme une correspondance. Notez que les résultats sont également dédupliqués à cette étape, de sorte que le même document ne sera pas renvoyé deux fois.
Si vous souhaitez que votre requête s'applique aux éléments individuels du tableau, plutôt qu'au tableau dans son ensemble, vous pouvez utiliser l'opérateur $elemMatch. Par exemple
> 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 ] }