Home > Enterprise >  MongoDB - Iterate to Array of objects and update the field as array
MongoDB - Iterate to Array of objects and update the field as array

Time:03-02

I am new to MongoDB. I have a collection that has multiple documents in which a particular document has a nested array structure. I need to iterate through this nested array and change the data type of the value of the iterated field.

Nested Array structure:

[
    {
        "identifier":{
            "type":"xxxx",
            "value":"1111"
        },
        "origin":"example.com",
        "score":8.0
    },
    {
        "identifier":{
            "type":"yyyyy",
            "value":"222"
        },
        "origin":"example.com",
        "score":8.0
    },
    {
        "identifier":{
            "type":"zzzzz",
            "value":"3333"
        },
        "origin":"https://olkdghf.com",
        "score":8.0
    }
]

The problem is I need to change the datatype without replacing the existing field value. But I am getting a new empty value instead of the original value.

My query:

db.SourceEntityv8test.find({"hasIdentifier.identifier.type": {$exists:true}}).sort({_id:1}).skip(0).limit(100).forEach(function(x) 
    {
        db.SourceEntityv8test.update({_id: x._id}, {$set:{"hasIdentifier.$[].identifier.type":[]}} );
    });

Expected output:

[
    {
        "identifier":{
            "type":[xxxx],
            "value":"1111"
        },
        "origin":"example.com",
        "score":8.0
    },
    {
        "identifier":{
            "type":[yyyyy],
            "value":"222"
        },
        "origin":"example.com",
        "score":8.0
    },
    {
        "identifier":{
            "type":[zzzzz],
            "value":"3333"
        },
        "origin":"example.com",
        "score":8.0
    }
]

Achieved output:

[
    {
        "identifier":{
            "type":[],
            "value":"1111"
        },
        "origin":"example.com",
        "score":8.0
    },
    {
        "identifier":{
            "type":[],
            "value":"222"
        },
        "origin":"example.com",
        "score":8.0
    },
    {
        "identifier":{
            "type":[],
            "value":"3333"
        },
        "origin":"example.com",
        "score":8.0
    }
]

CodePudding user response:

A bit complex. Expect that you need to achieve it by update with aggregation pipeline.

Concept:

  1. Update whole hasIdentifier array by 1.1.

1.1. Merge each document in hasIdentifier array with 1.1.1.

1.1.1. Merge identifier object with the document with type array.

db.SourceEntityv8test.update({_id: x._id},
[
  {
    $set: {
      hasIdentifier: {
        $map: {
          input: "$hasIdentifier",
          in: {
            $mergeObjects: [
              "$$this",
              {
                "identifier": {
                  $mergeObjects: [
                    "$$this.identifier",
                    {
                      type: [
                        "$$this.identifier.type"
                      ]
                    }
                  ]
                }
              }
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground

  • Related