Questo è in realtà ciò che il $elemMatch
operatore è per anche se viene spesso utilizzato in modo improprio. In sostanza, esegue le condizioni di query su ciascun elemento "all'interno" dell'array. Tutti gli argomenti MongoDB sono un'operazione "e" a meno che non venga esplicitamente chiamato diversamente:
db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2 } } })
Probabilmente vuoi anche "proiettare" anche qui se ti aspetti solo il campo abbinato e non l'intero documento:
db.collection.find(
{ "arr": { "$elemMatch": { "name": "b", "num": 2 } } },
{ "arr.$": 1 }
)
Infine per spiegare perché il tuo secondo tentativo non funziona, questa query:
db.collection.find({
"arr": [
{ "name": "b", "num": 2 }
]
})
Non corrisponde a nulla perché non esiste un vero documento in cui "arr" contiene un elemento singolare che corrisponde esattamente alle tue condizioni.
Il tuo primo esempio non è riuscito..:
db.collection.find({
$and: [
{ "arr.name": "b" },
{ "arr.num": 2 }
]
});
Perché ci sono diversi elementi dell'array che soddisfano le condizioni e questo non è solo considerato che entrambe le condizioni si applicano allo stesso elemento. Questo è ciò che $elemMatch
aggiunge, e quando hai bisogno di più di una condizione da abbinare, allora è qui che la usi.