Esto es realmente lo que $elemMatch
operador es para aunque a menudo se usa incorrectamente. Esencialmente realiza las condiciones de consulta en cada elemento "dentro" de la matriz. Todos los argumentos de MongoDB son una operación "y" a menos que se llame explícitamente de otra manera:
db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2 } } })
Probablemente también desee "proyectar" aquí si espera solo el campo coincidente y no todo el documento:
db.collection.find(
{ "arr": { "$elemMatch": { "name": "b", "num": 2 } } },
{ "arr.$": 1 }
)
Finalmente, para explicar por qué su segundo intento no funciona, esta consulta:
db.collection.find({
"arr": [
{ "name": "b", "num": 2 }
]
})
No coincide con nada porque no hay ningún documento real donde "arr" contenga un elemento singular que coincida exactamente con sus condiciones.
Tu primer ejemplo falló...:
db.collection.find({
$and: [
{ "arr.name": "b" },
{ "arr.num": 2 }
]
});
Porque hay varios elementos de la matriz que cumplen las condiciones y esto no se considera que ambas condiciones se aplican al mismo elemento. Eso es lo que $elemMatch
agrega, y cuando necesita más de una condición para que coincida, entonces aquí es donde lo usa.