Home > Back-end >  Concat array into other one inside same document MongoDB
Concat array into other one inside same document MongoDB

Time:05-14

Is there any way to insert the contents inside the nested field: "urls2.url_breed" inside "url_alternative.url" ?? I have many documents to process like this

    {  "_id": {    "$oid": "625f2900fe6aeb351381c3ff"  },  
    "breed": "Alaskan Malamute",  
    "origin": "United States (Alaska)",   
    "url_alternative": [
            {
              "urls": [
                "url23","url25"
              ]
            }
          ], 
    "url": "https://en.wikipedia.org/wiki/Alaskan_Malamute",  
    "img": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Alaskan_Malamute.jpg/300px-Alaskan_Malamute.jpg",
    "urls2": [
       {"_id": {"$oid": "627c04199569b8c2f566d15d"},
       "breed": "Alaskan Malamute",      
       "url_breed": [ "url1", "url2" ]}  
    ]}

Desired output:

     {  "_id": {    "$oid": "625f2900fe6aeb351381c3ff"  },  
        "breed": "Alaskan Malamute",  
        "origin": "United States (Alaska)",   
        "url_alternative": [
                {
                  "urls": [
                    "url1","url2",
                    "url23","url25"
                  ]
                }
              ], 
        "url": "https://en.wikipedia.org/wiki/Alaskan_Malamute",  
        "img": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Alaskan_Malamute.jpg/300px-Alaskan_Malamute.jpg",
    
        ]}

there are some cases when url_alternative is empty, but I still would like to insert the content of "urls2" because this one is always filled:

"url_alternative": [
        {
          "urls": [
            
          ]
        }
      ], 

CodePudding user response:

This could be complicated in query due to your highly nested structure, but the idea is simple. Construct tuples of the 2 arrays by $zip, iterate the result and use $concatArrays to "flatten them into an array.

db.collection.update({},
[
  {
    $addFields: {
      "url_alternative.urls": {
        "$reduce": {
          "input": {
            "$reduce": {
              "input": {
                "$zip": {
                  "inputs": [
                    "$url_alternative",
                    "$urls2"
                  ]
                }
              },
              "initialValue": [],
              "in": {
                "$concatArrays": [
                  "$$value",
                  "$$this.urls",
                  "$$this.url_breed"
                ]
              }
            }
          },
          "initialValue": [],
          "in": {
            "$concatArrays": [
              "$$value",
              "$$this"
            ]
          }
        }
      }
    }
  }
],
{
  multi: true
})

Here is the Mongo Playground for your reference.

  • Related