0

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.

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
Patryk
  • 29
  • 5

1 Answers1

1
  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

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
  • Thanks but still got same error. As long as I use only one `$[]` element filters so only `$[element1]` or only `$[element2]` it works. Don't have a clue why it works in your playground and not in my code. – Patryk Jul 02 '23 at 16:00