Home > Blockchain >  How to duplicate array element and modify a value at same time in MongoDb
How to duplicate array element and modify a value at same time in MongoDb

Time:12-09

I have the following document:

[
  {
    "_id": "a",
    "elements": [
      {
        "mode": "ALWAYS",
        "type": "RED",
        "number": "123"
      },
      {
        "mode": "ALWAYS",
        "type": "BLUE",
        "number": "99123124"
      }
    ]
  },
  {
    "_id": "b",
    "elements": [
      {
        "mode": "ALWAYS",
        "type": "RED",
        "number": "123"
      },
      {
        "mode": "ALWAYS",
        "type": "BLUE",
        "number": "123123123"
      }
    ]
  }
]

And I need to duplicate for single entry only the element of type "BLUE" but changing its type to GREEN. How can I accomplish that? I tried without luck using a db.col.push but I couldn't duplicate the specific entry "BLUE" of the array "elements".

This is the expected goal:

[
    {
      "_id": "a",
      "elements": [
        {
          "mode": "ALWAYS",
          "type": "RED",
          "number": "123"
        },
        {
          "mode": "ALWAYS",
          "type": "BLUE",
          "number": "99123124"
        },
        {
          "mode": "ALWAYS",
          "type": "GREEN",
          "number": "99123124"
        }
      ]
    },
    {
      "_id": "b",
      "elements": [
        {
          "mode": "ALWAYS",
          "type": "RED",
          "number": "123"
        },
        {
          "mode": "ALWAYS",
          "type": "BLUE",
          "number": "123123123"
        },
        {
            "mode": "ALWAYS",
            "type": "GREEN",
            "number": "123123123"
        }
      ]
    }
  ]

CodePudding user response:

Query

  • pipeline update requires MongoDB >= 4.2
  • map and convert the blues to greens
  • filter to remove those that weren't blues
  • add those greens to the initial elements array

Test code here

update(
{},
[{"$set": 
   {"elements": 
     {"$concatArrays": 
       ["$elements",
        {"$filter": 
          {"input": 
            {"$map": 
              {"input": "$elements",
               "in": 
               {"$cond": 
                 [{"$eq": ["$$this.type", "BLUE"]},
                  {"$mergeObjects": ["$$this", {"type": "GREEN"}]}, null]}}},
            "cond": {"$ne": ["$$this", null]}}}]}}}])
  • Related