Updating nested array fields with values from another field in the nested document

The reason you cannot use arrayFilters isn’t because of multiple levels of nesting (it works with that) but because you want to set the value to something that references another field in the document. That can only be done with aggregation expressions so you need pipeline syntax for this.

Given a document:

{ l1: [
        { l2: [ { value: 1}, {value: 2} ] }
] }

You can do this update to double every value

db.coll.update({}, [ {$map:{
                       input: "$l1", as: "l1", in: {$map:{
                               input: "$$l1.l2", as: "l2", in: {$mergeObjects:[ 
                                    "$$l2",
                                    {value: {$multiply:[ 2, "$$l2.value"] }}
                               ]}
                       }}
                    }} ], {multi:true})

If you don’t want to update every element, you would add a conditional $cond expression and then either pass on $$l1 (or $$l2) or the replacement object.

HTH,
Asya

1 Like