Question de requête mongo $gt, $ lt

J'ai une requête ci-dessous. Je veux obtenir des éléments entre 4 et 6, donc seul a: 1 devrait correspondre car il a la valeur 5 dans B.

> db.test.find({ b : { $gt :  4  }, b: {$lt : 6}});
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
>

Quelqu'un peut-il dire pourquoi a:2 correspond à cette requête? Je ne vois pas vraiment pourquoi il est renvoyé.

J'ai aussi essayé ce qui était spécifié dans le tutoriel mais id ne semblait pas fonctionner:

> db.test.find({ b : { $gt :  4, $lt : 6}});
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
>

Et celui-ci pour éviter toute confusion concernant GT / GTE

> db.test.find({b: {$gt: 4.5, $lt: 5.5}});
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
>

Seul un: 1 doit être retourné.

Comme suggéré, j'ai essayé $elemMatch mais cela ne semble pas non plus fonctionner (les objectIds sont différents parce que je suis sur une machine différente)

> db.test.find();
{ "_id" : ObjectId("4d5a24a5e82e00000000433f"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d5a24bbe82e000000004340"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
> db.test.find({b: {$elemMatch: {$gt : 4, $lt: 6 }}});
>

Aucun document n'a été retourné.

21
demandé sur paullb 2011-02-11 09:24:45

4 réponses

C'est un sujet très déroutant. Je travaille chez 10gen et j'ai dû passer un moment à m'enrouler la tête;)

Parcourons 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 contre chaque élément du tableau, mais plutôt contre le tableau dans son ensemble.

La comparaison se fait en trois étapes:

Étape 1: Trouvez tous les documents où b a une valeur supérieure à 4

B: [2,4,6,8] correspond parce que 6 & 8 sont supérieurs à 4

Étape 2: Trouvez tous les documents où b a une valeur inférieure à 6

B: [2,4,6,8] correspond car 2 & 4 sont inférieurs à 6

Étape 3 : trouvez l'ensemble de documents correspondant aux deux étapes 1 et 2.

Le document avec b: [2,4,6,8] correspond aux deux étapes 1 et 2 de sorte qu'il est retourné comme une correspondance. Notez que les résultats sont également dupliqués à cette étape, de sorte que le même document ne sera pas renvoyé deux fois.

Si vous voulez 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 ] }
58
répondu jared 2011-02-11 23:27:14

$ gt

Syntax: {field: {$gt: value} }

Par exemple:

db.inventory.find( { qty: { $gt: 20 } } )

$ lt

Syntax: {field: {$lt: value} }

Par exemple:

db.inventory.find( { qty: { $lt: 20 } } )

Eg2:

db.inventory.find({ qty : { $gt :  20, $lt : 60}});
4
répondu Jijo Paulose 2016-02-25 10:29:06
.find( {$and:[ {b:{$gt:4}}, {b:{$lt:6}} ]} )
0
répondu Anon 2015-10-28 07:44:11

Parce que vous n'avez pas vérifié la documentation.

Voir

Http://www.mongodb.org/display/DOCS/Advanced+Requêtes

Et vérifiez "plages" sur la page.

Votre syntaxe de requête n'est pas non plus correcte (comparer avec l'exemple)

Votre partie "pourquoi a:2" de la question N'a aucun sens puisque 'a' n'est pas impliqué dans votre requête. Si vous souhaitez rechercher un:1, alors vous devez l'inclure dans votre requête.

Gardez à l'esprit que toutes les clauses de requête sont et combinés par défaut, sauf si vous utilisez l'opérateur $or.

-9
répondu Andreas Jung 2011-02-11 06:33:01