1

I know it's possible to update specific array elements, as documented here: https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/

Also, I'm aware it's possible to use a field value to update the value of another field, as explained here: Update MongoDB field using value of another field

What I need is a combination of the two.

Let's say I have this in the DB:

{
  a: [
     {
        aa: 10
     },
     {
        cc: 15
     }

  ]
}

Now, I want to add a field bb to the array documents with aa's value, but only if aa exists. So the output is:

{
  a: [
     {
        aa: 10,
        bb: 10
     },
     {
        cc: 15
     }

  ]
}

How can I achieve this?

turivishal
  • 34,368
  • 7
  • 36
  • 59
Elliko
  • 71
  • 1
  • 10
  • Sounds like you should make a filter that finds all documents having the 'aa' and use that list for the update. I.e. look at [updateMany](https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#mongodb-method-db.collection.updateMany) – JHBonarius Jun 01 '21 at 11:02
  • Why aggregation update you referred doesn't work for you? You can use all aggregation functions within the $set. – Alex Blex Jun 01 '21 at 11:03
  • @AlexBlex I needed a way to update only specific elements in the array matching a certain filter. The arrayFilters is not supported in the aggregation syntax. Apparently what I needed is $map per turivishal answer. – Elliko Jun 02 '21 at 12:58
  • @JHBonarius this is not enough, I needed to update specific elements in aa according to a condition. – Elliko Jun 02 '21 at 12:59

1 Answers1

1

Try update with aggregation pipeline starting from MongoDB 4.2,

  • match field exists a condition
  • $map to iterate loop of a array
  • $cond check condition if aa field is not null then add new field bb with value of aa and merge with current object using $mergeObjects, otherwise return current object
db.collection.update(
  { "a.aa": { $exists: true } },
  [{
    $set: {
      a: {
        $map: {
          input: "$a",
          in: {
            $cond: [
              { $ne: ["$$this.aa", null] },
              { $mergeObjects: ["$$this", { bb: "$$this.aa" }] }
              "$$this",
            ]
          }
        }
      }
    }
  }],
  { multi: true }
)

Playground

turivishal
  • 34,368
  • 7
  • 36
  • 59