Home > Enterprise >  How to update the value to the nested object array in mongodb document?
How to update the value to the nested object array in mongodb document?

Time:05-06

I have following document on which the update needs to be done.


    {
        "_id": "Colorcode_1",
        "Combination": [
            {
                "color": [
                    {
                        "mixture": [
                            "Red",
                            "Green"
                        ]
                    }
                ],
                "code": "Maroon"
            },
            {
                "color": [
                    {
                        "mixture": [
                            "Yellow",
                            "Green"
                        ]
                    }
                ],
                "code": "Light Green"
            }
        ]
    }

Now what I need to do is to update the document by adding the value "Blue" in the "mixture" field where "code" is "Maroon". Something like this. This needs to be done using $addToSet


    {
        "_id": "Colorcode_1",
        "Combination": [
            {
                "color": [
                    {
                        "mixture": [
                            "Red",
                            "Green",
                            "Blue"
                        ]
                    }
                ],
                "code": "Maroon"
            },
            {
                "color": [
                    {
                        "mixture": [
                            "Yellow",
                            "Green"
                        ]
                    }
                ],
                "code": "Light Green"
            }
        ]
    }

Any help regarding this would be highly helpful.

CodePudding user response:

I found this update difficult because of the data model, and I'm hoping you'll get a better/simpler answer.

Anyway, here's one way you could do it. I would test this on more/different data to insure it's correct.

db.collection.update({
  "_id": "Colorcode_1",
  "Combination.code": "Maroon"
},
[
  {
    "$set": {
      "Combination": {
        "$map": {
          "input": "$Combination",
          "as": "elem",
          "in": {
            "$cond": [
              { "$eq": [ "$$elem.code", "Maroon" ] },
              {
                "$mergeObjects": [
                  "$$elem",
                  {
                    "color": {
                      "$map": {
                        "input": "$$elem.color",
                        "as": "colorElem",
                        "in": {
                          "$cond": [
                            {
                              "$reduce": {
                                "input": { "$objectToArray": "$$colorElem" },
                                "initialValue": false,
                                "in": {
                                  "$or": [
                                    "$$value",
                                    { "$eq": [ "$$this.k", "mixture" ] }
                                  ]
                                }
                              }
                            },
                            {
                              "mixture": {
                                "$setUnion": [ "$$colorElem.mixture", [ "Blue" ] ]
                              }
                            },
                            "$$colorElem"
                          ]
                        }
                      }
                    }
                  }
                ]
              },
              "$$elem"
            ]
          }
        }
      }
    }
  }
])

Try it on mongoplayground.net.

CodePudding user response:

Here is option with arrayFilters:

db.collection.update({
   "Combination.code": "Maroon"
  },
  {
   "$addToSet": {
    "Combination.$[x].color.$[y].mixture": "Blue"
   }
 },
 {
  arrayFilters: [
  {
    "x.code": "Maroon"
  },
  {
   "y.mixture": {
    $exists: true
  }
}
 ]
})

Explained:

  1. Filter all documents having code:Marron , good to have index on this field if collection is big
  2. Use arrayFilter x.code to add the array element to mixture if mixture exists ( identified by y arrayFilter)

playground

  • Related