Съвсем стар въпрос, но буквално нито един от предложените отговори не е добър.
TLDR :
Не можете да използвате $elemMatch на етап $project. но можете да постигнете същия резултат, като използвате други оператори за агрегиране като $filter.
db.itens.aggregate([
{
$project: {
compList: {
$filter: {
input: "$complist",
as: "item",
cond: {$eq: ["$$item.a", 1]}
}
}
}
}
])
И ако искате само първия елемент от масива, който съответства на условието, подобно на това, което прави $elemMatch, можете да включите $arrayElemAt
Подробно обяснение :
Първо нека разберем $elemMatch:
$elemMatch е израз на заявка, докато тази негова версия на проекция съществува, това се отнася до проекция на заявка, а не до етап на агрегиране на $project.
И какво тогава? какво общо има това с нещо? Е, етапът на $project има определена входна структура, която може да има, докато тази, която искаме да използваме, е:
<поле>:<израз>
Какво е валиден израз?
Изразите могат да включват пътеки на полета, литерали, системни променливи, обекти на изрази и оператори на изрази. Изразите могат да бъдат вложени.
Искаме да използваме изразен оператор, но както можете да видите от $elemMatch
на документа не е част от него. следователно това не е валиден израз, който да се използва в агрегиране $project
етап.