MongoDB - Update deep nested array

44 views Asked by At

I'm using Mongoose and ExpressJS

I have a schema like this:

{
  name: 'test',
  array1: [
    {
      type: 'big',
      array2: [
        {
          name: 'xyz',
          value: 1
        }
      ]
    }
  ]
}

I have to do some bulk inserts to array2 to each document that has array1.type === 'big'. The code below works well.

myCollection.updateMany(
  { array: {$ne: []}, ...someOtherFilters },
  { $push: { { [`array1.$[element].array2`]: newObject } },
  { arrayFilters: [{ 'element.type': 'big' }] }
)

Now I want to be able to update properties in array2 objects. I want to update array2.value everywhere where array1.type === 'big' and array2.name === 'xyz'. I try this:

myCollection.updateMany(
  { array: {$ne: []}, ...someOtherFilters },
  { $set: { { [`array1.$[element1].array2.$[element2].value`]: 100 } },
  { arrayFilters: [{ 'element1.type': 'big', 'element2.name': 'xyz' }] }
)

What I got:

Error: Could not find path "array1.0.array2.0.name" in schema

Don't know how I can manage that.

1

There are 1 answers

1
Yong Shun On
  1. Will recommend the modify the filter part to determine whether the document contains array1.type === 'big' and array1.array2.name === 'xyz' via $elemMatch.

  2. The arrayFilters part was incorrect. element1 and element2 are different identifiers, thus they should be separated into different objects.

  3. The syntax for $set is incorrect.

Your query should be as below:

myCollection.updateMany({
  array1: {
    $elemMatch: {
      "type": "big",
      "array2": {
        $elemMatch: {
          "name": "xyz"
        }
      }
    }
  },
  //...someOtherFilters
  
},
{
  $set: {
    "array1.$[element1].array2.$[element2].value": 100
  }
},
{
  arrayFilters: [
    {
      "element1.type": "big"
    },
    {
      "element2.name": "xyz"
    }
  ]
})

Demo @ Mongo Playground