Você não pode retornar vários elementos de uma matriz que correspondam aos seus critérios em qualquer forma de um
.find()
básico inquerir. Para corresponder a mais de um elemento, você precisa usar o .aggregate()
método em vez disso. A principal diferença aqui é que a "consulta" faz exatamente o que se destina a fazer e corresponde aos "documentos" que atendem às suas condições. Você pode tentar usar o
$
posicional operador dentro de um argumento de projeção, mas as regras são que ele corresponderá apenas ao "primeiro" elemento da matriz que corresponde às condições da consulta. Para "filtrar" vários elementos do array, proceda da seguinte forma:
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Unwind the array to denormalize
{ "$unwind": "$filtermetric" },
// Match specific array elements
{ "$match": { "filtermetric.class": "s2" } },
// Group back to array form
{ "$group": {
"_id": "$_id",
"filtermetric": { "$push": "$filtermetric" }
}}
])
Nas versões modernas do MongoDB que são a versão 2.6 ou superior, você pode fazer isso com
$redact
:db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Redact the entries that do not match
{ "$redact": {
"$cond": [
{ "$eq": [ { "$ifNull": [ "$class", "s2" ] }, "s2" ] },
"$$DESCEND",
"$$PRUNE"
]
}}
])
Essa é provavelmente sua opção mais eficiente, mas é recursiva, portanto, considere primeiro a estrutura do seu documento, pois o mesmo campo nomeado não pode existir com nenhuma outra condição em nenhum nível.
Possivelmente mais seguro, mas útil apenas onde os resultados na matriz são "verdadeiramente exclusivos" é essa técnica com
$map
e $setDifference
:db.sample.aggregate([
{ "$project": {
"filtermetric": { "$setDifference": [
{ "$map": [
"input": "$filtermetric",
"as": "el",
"in": {"$cond": [
{ "$eq": [ "$$el.class", "s2" ] },
"$$el",
false
]}
]},
[false]
]}
}}
])
Observando também que tanto no
$group
e $project
estágios de pipeline operacionais que você precisa para especificar todos os campos que você pretende retornar em seus documentos de resultados desse estágio. A nota final é que
$elemMatch
não é necessário quando você está apenas consultando o valor de uma única chave em uma matriz. A "notação de ponto" é preferida e recomendada ao acessar apenas uma única chave da matriz. $elemMatch
só deve ser necessário quando "múltiplas" chaves no documento dentro da matriz "elemento" precisam corresponder a uma condição de consulta.