Reputation: 23
I have a complex structure of JSON object which contain (N) number of embedded arrays. A single entry is an object with two fields : @name
and content
. I need to filter them in projection stage (without using $unwind
) to get one specific object where @name
field is equals to specific value:
productCategory: {$filter: {
input: '$characteristics.attributeGroup.attribute',
as: 'attribute',
cond: {
...?
}}
The $characteristics.attributeGroup.attribute
input returns the above structure. I was trying to use something like that in $cond: { $eq: ['$$attribute.@name', 'averageRating'] }
but it doesn't work.
Could you please help me to find out a solution here?
Thanks in advance!
Upvotes: 0
Views: 402
Reputation: 36114
You can try,
$reduce
to iterate loop of attributeGroup
array, and back merge objects using $mergeObjects
object
then again check second condition if @name matched then return values otherwise move to else condition$reduce
to iterate loop of attribute
array, check condition if name match then return valuelet name = "Artikelhinweise";
db.collection.aggregate([
{ $match: { "attributeGroup.attribute.@name": name } }, // name pass here
{
$project: {
attributeGroup: {
$reduce: {
input: "$attributeGroup",
initialValue: {},
in: {
$mergeObjects: [
"$$value",
{
$cond: [
{ $eq: [{ $type: "$$this.attribute" }, "object"] },
{
$cond: [
{ $eq: ["$$this.attribute.@name", name] }, // name pass here
{
"@name": "$$this.attribute.@name",
"content": "$$this.attribute.content"
},
"$$value"
]
},
{
$reduce: {
input: "$$this.attribute",
initialValue: {},
in: {
$cond: [
{ $eq: ["$$this.@name", name] }, // name pass here
{
"@name": "$$this.@name",
"content": "$$this.content"
},
"$$value"
]
}
}
}
]
}
]
}
}
}
}
}
])
Upvotes: 1