Na verdade, é isso que o
$elemMatch
operador é para mesmo que muitas vezes seja mal utilizado. Ele essencialmente executa as condições de consulta em cada elemento "dentro" da matriz. Todos os argumentos do MongoDB são uma operação "and", a menos que explicitamente chamado de outra forma:db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2 } } })
Você provavelmente também deseja "projetar" aqui se estiver esperando apenas o campo correspondente e não todo o documento:
db.collection.find(
{ "arr": { "$elemMatch": { "name": "b", "num": 2 } } },
{ "arr.$": 1 }
)
Finalmente, para explicar por que sua segunda tentativa não funciona, esta consulta:
db.collection.find({
"arr": [
{ "name": "b", "num": 2 }
]
})
Não corresponde a nada porque não existe um documento real em que "arr" contenha um elemento singular que corresponda exatamente às suas condições.
Seu primeiro exemplo falhou ..:
db.collection.find({
$and: [
{ "arr.name": "b" },
{ "arr.num": 2 }
]
});
Porque existem vários elementos de array que satisfazem as condições e isso não é considerado apenas que ambas as condições se aplicam ao mesmo elemento. É isso que
$elemMatch
adiciona e quando você precisa de mais de uma condição para corresponder, é aqui que você a usa.