Мангуст извлекает первый элемент подмассива после фильтрации
У меня есть массив в поддокументе, как это
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" : [
{
"language" : "en",
"desc": "day description"
},
{
"language" : "es",
"desc": "descripcion del dia"
}
]
}
Я хочу отфильтровать вложенные документы по языку. Я могу сделать это так
db.test.aggregate([
{ $project: {
descDay: {$filter: {
input: '$list',
as: 'item',
cond: {$gt: ['$$item.language', 'en']}
}}
}}
])
это дало бы мне что-то вроде
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" : [
{
"language" : "en",
"desc": "day description"
}]
}
но мне нужно, чтобы descDay был документом, а не массивом, что-то вроде этого:
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" :
{
"language" : "en",
"desc": "day description"
}
}
как я могу получить это?
1 ответ
Решение
Ты можешь использовать $unwind
размотать одноэлементный descDay
массив в объект:
db.test.aggregate([
{ $project: {
descDay: {$filter: {
input: '$descDay',
as: 'item',
cond: {$eq: ['$$item.language', 'en']}
}}
}},
{ $unwind: '$descDay' }
])
Или, как упоминалось @chridam, вы можете использовать $arrayElemAt
в $project
и непосредственно проецируем первый элемент:
db.test.aggregate([
{ $project: {descDay: {$arrayElemAt: [
{$filter: {
input: '$descDay',
as: 'item',
cond: {$eq: ['$$item.language', 'en']}
}}, 0]
}}}
])
В любом случае на выходе получается:
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" : {
"language" : "en",
"desc" : "day description"
}
}
Обратите внимание, что мне пришлось исправить пару проблем в вашем исходном запросе:
'$list'
в'$descDay'
$gt
в$eq