2

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?

4
  • 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 Commented Jun 1, 2021 at 11:02
  • Why aggregation update you referred doesn't work for you? You can use all aggregation functions within the $set. Commented Jun 1, 2021 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. Commented Jun 2, 2021 at 12:58
  • @JHBonarius this is not enough, I needed to update specific elements in aa according to a condition. Commented Jun 2, 2021 at 12:59

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.