skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search