Suponha que você tenha os seguintes documentos em minha coleção:
{
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
{
"shape":"square",
"color":"blue"
},
{
"shape":"circle",
"color":"red"
}
]
},
{
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
{
"shape":"square",
"color":"black"
},
{
"shape":"circle",
"color":"green"
}
]
}
Faça a consulta:
db.test.find({"shapes.color": "red"}, {"shapes.color": 1})
Ou
db.test.find({shapes: {"$elemMatch": {color: "red"}}}, {"shapes.color": 1})
Retorna o documento correspondente (Documento 1) , mas sempre com TODOS os itens da matriz em shapes
:
{ "shapes":
[
{"shape": "square", "color": "blue"},
{"shape": "circle", "color": "red"}
]
}
No entanto, gostaria de obter o documento (Documento 1) apenas com a matriz que contém color=red
:
{ "shapes":
[
{"shape": "circle", "color": "red"}
]
}
Como posso fazer isso?
aggregate
.db.test.find({}, {shapes: {$elemMatch: {color: "red"}}});
O novo Aggregation Framework no MongoDB 2.2+ fornece uma alternativa ao Map / Reduce. O
$unwind
operador pode ser usado para separar suashapes
matriz em um fluxo de documentos que podem ser comparados:Resulta em:
fonte
$elemMatch
é outra opção. Na verdade, cheguei aqui por meio de uma pergunta do Grupo do Google em que $ elemMatch não funcionaria porque retorna apenas a primeira correspondência por documento.{ $project : { shapes : 1 } }
- o que parecia funcionar e seria útil se os documentos anexos fossem grandes e você desejasse apenas visualizar osshapes
valores-chave.Outra maneira interessante é usar $ redact , que é um dos novos recursos de agregação do MongoDB 2.6 . Se você estiver usando o 2.6, não precisará de um $ desenrolar, o que pode causar problemas de desempenho se você tiver grandes matrizes.
$redact
"restringe o conteúdo dos documentos com base nas informações armazenadas nos próprios documentos" . Portanto, ele será executado apenas dentro do documento . Basicamente, ele digitaliza seu documento de cima para baixo e verifica se ele corresponde à suaif
condição$cond
, se houver, ele manterá o conteúdo ($$DESCEND
) ou removerá ($$PRUNE
).No exemplo acima, primeiro
$match
retorna todoshapes
matriz e $ redact a reduz para o resultado esperado.Observe que
{$not:"$color"}
é necessário, porque ele também digitalizará o documento superior e, se$redact
não encontrar umcolor
campo no nível superior, isso retornará, ofalse
que poderá remover o documento inteiro que não queremos.fonte
$match
como seu primeiro estágio agregadoO parâmetro do seletor de campo é limitado às propriedades completas. Não pode ser usado para selecionar parte de uma matriz, apenas a matriz inteira. Eu tentei usar o operador posicional $ , mas isso não funcionou.
A maneira mais fácil é filtrar apenas as formas no cliente .
Se você realmente precisa da saída correta diretamente do MongoDB, pode usar uma redução de mapa para filtrar as formas.
fonte
Melhor você pode consultar o elemento da matriz correspondente usando,
$slice
é útil retornar o objeto significativo em uma matriz.$slice
é útil quando você conhece o índice do elemento, mas às vezes deseja que qualquer elemento da matriz corresponda aos seus critérios. Você pode retornar o elemento correspondente com o$
operador.fonte
SAÍDAS
fonte
A sintaxe para encontrar no mongodb é
e a segunda consulta que você escreveu, ou seja,
nisto você usou o
$elemMatch
operador na parte de consulta, enquanto que se você usar esse operador na parte de projeção, obterá o resultado desejado. Você pode anotar sua consulta comoIsso lhe dará o resultado desejado.
fonte
"shapes.color":"red"
o parâmetro de consulta (o primeiro parâmetro do método find) não é necessário. Você pode substituí-lo{}
e obter os mesmos resultados.Graças a JohnnyHK .
Aqui eu só quero adicionar um uso mais complexo.
fonte
Você só precisa executar a consulta
a saída desta consulta é
conforme o esperado, ele fornece o campo exato da matriz que corresponde à cor: 'vermelho'.
fonte
junto com $ project, será mais apropriado que outros elementos de correspondência sábios sejam combinados com outros elementos no documento.
fonte
Da mesma forma, você pode encontrar para os múltiplos
fonte
$match
reduzir o espaço e, em seguida,$filter
manter o que você deseja, sobrescrevendo o campo de entrada (use a saída de$filter
no camposhapes
para$project
retornar aoshapes
. Nota de estilo: melhor não usar o nome do campo como oas
argumento porque isso pode levar a confusão mais tarde com$$shape
e$shape
.. Eu prefirozz
como oas
campo porque realmente se destaca.fonte
Use a função de agregação e
$project
para obter um campo de objeto específico no documentoresultado:
fonte
Embora a pergunta tenha sido feita há 9,6 anos, isso tem sido de grande ajuda para inúmeras pessoas, sendo eu uma delas. Obrigado a todos por todas as suas perguntas, sugestões e respostas. Pegando uma das respostas aqui .. Descobri que o método a seguir também pode ser usado para projetar outros campos no documento pai. Isso pode ser útil para alguém.
Para o documento a seguir, era necessário descobrir se um funcionário (emp # 7839) tem seu histórico de férias definido para o ano 2020. O histórico de férias é implementado como um documento incorporado ao documento do funcionário.
fonte