I have array in subdocument like this
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" : [
{
"language" : "en",
"desc": "day description"
},
{
"language" : "es",
"desc": "descripcion del dia"
}
]
}
I want to filter the subdocuments by language. I can do that like this
db.test.aggregate([
{ $project: {
descDay: {$filter: {
input: '$list',
as: 'item',
cond: {$gt: ['$$item.language', 'en']}
}}
}}
])
that would give me something like
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" : [
{
"language" : "en",
"desc": "day description"
}]
}
but I need descDay to be a document not an array, something like this:
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" :
{
"language" : "en",
"desc": "day description"
}
}
how can I get that?
You can use $unwind
to unwind the single-element descDay
array into an object:
db.test.aggregate([
{ $project: {
descDay: {$filter: {
input: '$descDay',
as: 'item',
cond: {$eq: ['$$item.language', 'en']}
}}
}},
{ $unwind: '$descDay' }
])
Or, as @chridam mentioned, you can use $arrayElemAt
in the $project
and directly project the first element:
db.test.aggregate([
{ $project: {descDay: {$arrayElemAt: [
{$filter: {
input: '$descDay',
as: 'item',
cond: {$eq: ['$$item.language', 'en']}
}}, 0]
}}}
])
Either way the output is:
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"descDay" : {
"language" : "en",
"desc" : "day description"
}
}
Note that I had to fix a couple problems in your original query:
'$list'
to '$descDay'
$gt
to $eq