Bastante na pergunta antiga, mas literalmente nenhuma das respostas propostas é boa.
TLDR :
Você não pode usar $elemMatch em um estágio $project. mas você pode obter o mesmo resultado usando outros operadores de agregação como $filter.
db.itens.aggregate([
{
$project: {
compList: {
$filter: {
input: "$complist",
as: "item",
cond: {$eq: ["$$item.a", 1]}
}
}
}
}
])
E se você quiser apenas o primeiro item da matriz que corresponda à condição de forma semelhante ao que $elemMatch faz, você pode incorporar $arrayElemAt
Explicação detalhada :
Primeiro vamos entender $elemMatch:
$elemMatch é uma expressão de consulta, embora também exista essa versão de projeção, isso se refere a uma projeção de consulta e não ao estágio de agregação do projeto $.
E daí? O que isso tem a ver com alguma coisa? bem, um estágio $project tem certa estrutura de entrada que pode ter enquanto o que queremos usar é:
:
O que é uma expressão válida?
As expressões podem incluir caminhos de campo, literais, variáveis de sistema, objetos de expressão e operadores de expressão. As expressões podem ser aninhadas.
Então, queremos usar um operador de expressão, mas como você pode ver no
$elemMatch
do documento não faz parte. portanto, não é uma expressão válida para ser usada em uma agregação $project
etapa.