Je vais expliquer cela avec un exemple. Considérez la collection arrays
. Il a un champ appelé arr
qui est un tableau de documents intégrés (avec les champs a
et b
).
Certains documents dans les arrays
collecte :
{ "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
{ "_id" : 2, "arr" : [ { "a" : "a1", "b" : "b11" }, { "a" : "a2", "b" : "b22" } ] }
{ "_id" : 3, "arr" : [ { "a" : "a2", "b" : "b1" }, { "a" : "a", "b" : "b1" } ] }
{ "_id" : 4, "arr" : [ { "a" : "a1", "b" : "b91" }, { "a" : "a29", "b" : "b1" } ] }
Je veux trouver tous les documents avec le tableau des champs de documents intégrés a="a1"
ET b="b1"
. Notez que cela doit être dans le même élément embedded-document du tableau. J'utilise $elemMatch pour cela et obtenez le résultat souhaité.
> db.arrays.find( { arr: { $elemMatch: { a: "a1", b: "b1" } } } )
==>
{ "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
Maintenant, si j'utilise le $et opérateur comme dans la requête suivante, les résultats ne sont pas corrects. Comme vous pouvez le voir, un document supplémentaire est sélectionné. La requête a fonctionné avec le tableau des champs de document intégré a="a1"
OU b="b1"
.
> db.arrays.find({$and: [ { "arr.a": "a1" }, { "arr.b": "b1" } ] } )
==>
{ "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
{ "_id" : 4, "arr" : [ { "a" : "a1", "b" : "b91" }, { "a" : "a29", "b" : "b1" } ] }
Donc, en utilisant le $and
L'opérateur n'est PAS destiné à cet usage (c'est-à-dire, interroger sur plusieurs champs d'un tableau de sous-documents).
De plus, pour interroger sur un tableau de champ de document intégré (un seul champ ) le $elemMatch
n'est pas obligatoire, par exemple :
> db.arrays.find( { "arr.a": "a2" } )
==>
{ "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
{ "_id" : 2, "arr" : [ { "a" : "a1", "b" : "b11" }, { "a" : "a2", "b" : "b22" } ] }
{ "_id" : 3, "arr" : [ { "a" : "a2", "b" : "b1" }, { "a" : "a", "b" : "b1" } ] }