To właśnie $elemMatch
operator jest przeznaczony, chociaż często jest niewłaściwie używany. Zasadniczo wykonuje warunki zapytania na każdym elemencie "w" tablicy. Wszystkie argumenty MongoDB są operacją "i", chyba że wyraźnie nazwano inaczej:
db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2 } } })
Prawdopodobnie również tutaj chcesz „zaprojektować”, jeśli oczekujesz tylko dopasowanego pola, a nie całego dokumentu:
db.collection.find(
{ "arr": { "$elemMatch": { "name": "b", "num": 2 } } },
{ "arr.$": 1 }
)
Na koniec, aby wyjaśnić, dlaczego druga próba nie działa, to zapytanie:
db.collection.find({
"arr": [
{ "name": "b", "num": 2 }
]
})
Nie pasuje do niczego, ponieważ nie istnieje żaden dokument, w którym „arr” zawiera pojedynczy element dokładnie pasujący do twoich warunków.
Twój pierwszy przykład się nie powiódł...:
db.collection.find({
$and: [
{ "arr.name": "b" },
{ "arr.num": 2 }
]
});
Ponieważ istnieje kilka elementów tablicy, które spełniają warunki i nie uważa się, że oba warunki mają zastosowanie do tego samego elementu. To właśnie $elemMatch
dodaje, a kiedy potrzebujesz więcej niż jednego warunku do spełnienia, to właśnie tutaj go używasz.