Queries in MongoDB machen default eine UND-Operation. Wendet man dies jedoch auf Array Elemente an, kann dies falsche Ergebnisse liefern, wenn man den Query nicht richtig anwendet.
$ mongo
> db.people.insert({_id: "rms", first_name: "richard", last_name: "stallman"}) > db.people.insert({_id: "steve", first_name: "steve", last_name: "ballmer"}) > > db.people.find() { "_id" : "rms", "first_name" : "richard", "last_name" : "stallman" } { "_id" : "steve", "first_name" : "steve", "last_name" : "ballmer" } > > db.people.find({first_name: "richard", last_name: "ballmer"}) >
Der letzte Query liefert keine Ausgabe, da es keinen Datensatz gibt,
der als Vornamen richard
und als Nachnamen ballmer
hat.
Das Gleiche könnte man erwarten bei folgender Situation:
> db.tags.insert({_id: "foo", tags: ["tag1", "tag2", "tag3"]}) > db.tags.insert({_id: "bar", tags: ["tag4", "tag5", "tag6"]}) > > db.tags.find() { "_id" : "foo", "tags" : [ "tag1", "tag2", "tag3" ] } { "_id" : "bar", "tags" : [ "tag4", "tag5", "tag6" ] } > > db.tags.find({tags: "tag1", tags: "tag4"}, {_id: true} ) { "_id" : "bar" } > > db.tags.find({tags: "tag4", tags: "tag1"}, {_id: true} ) { "_id" : "foo" }
Wie man sieht, erhält man ein Resultat, obwohl es keinen Datensatz gibt,
in dem das Tag tag1
und tag4
vorkommt.
Es scheint, als überschreibt bei mehrmaliger Angabe des gleichen Keys, der letzte davon alle vorhergehenden:
Ein
db.tags.find({tags: "tag1", tags: "tag4"}, {_id: true} )
endet also als
db.tags.find({tags: "tag4"}, {_id: true} )
bzw.
db.tags.find({tags: "tag4", tags: "tag1"}, {_id: true} )
als
db.tags.find({tags: "tag1"}, {_id: true} )
Eine UND-Verknüpfung bei Array Elementen muss daher anders angeben werden:
> db.tags.find({ $and: [ {tags: "tag1" }, {tags: "tag4"} ] }, {_id: true} ) >
> db.tags.find({ $and: [ {tags: "tag4" }, {tags: "tag1"} ] }, {_id: true} ) >
> db.tags.find({ $and: [ {tags: "tag1" }, {tags: "tag3"} ] }, {_id: true} ) { "_id" : "foo" }
Oder etwas eleganter:
> db.tags.find({ tags: { $all: ["tag1", "tag4"] } } , {_id: true} ) >
> db.tags.find({ tags: { $all: ["tag1", "tag3"] } } , {_id: true} ) { "_id" : "foo" }