Wyjaśnię to na przykładzie. Rozważ kolekcję arrays
. Ma pole o nazwie arr
czyli tablica osadzonych dokumentów (z polami a
i b
).
Niektóre dokumenty w arrays
kolekcja:
{ "_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" } ] }
Chcę znaleźć wszystkie dokumenty z polami osadzonego dokumentu w tablicy a="a1"
ORAZ b="b1"
. Zauważ, że musi to znajdować się w tym samym elemencie osadzonego dokumentu tablicy. Używam $elemMatch w tym celu i uzyskaj pożądany rezultat.
> db.arrays.find( { arr: { $elemMatch: { a: "a1", b: "b1" } } } )
==>
{ "_id" : 1, "arr" : [ { "a" : "a1", "b" : "b1" }, { "a" : "a2", "b" : "b2" } ] }
Teraz, jeśli użyję $i operator jak w poniższym zapytaniu, wyniki nie są poprawne. Jak widać wybrany jest dodatkowy dokument. Zapytanie działało z polami dokumentu osadzonego w tablicy a="a1"
LUB 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" } ] }
Tak więc, używając $and
operator NIE jest przeznaczony do tego celu (tj. do wykonywania zapytań w wielu polach tablicy poddokumentów).
Ponadto, aby zapytać o pole dokumentu osadzonego w tablicy (tylko jedno pole ) $elemMatch
nie jest wymagane, na przykład:
> 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" } ] }