Home > Net >  Update nested array in a mongo document
Update nested array in a mongo document

Time:11-04

I have below collection

{
    "_id" : ObjectId("5d7e6c54c23c210001108556"),
    “parentId" : "5d0162ba69cf130001a16115",
    "tasks" : [
        {
            "_id" : "ae60a8f1",
            "taskMetaDataIds” : [
                ObjectId("5d55a648e2f7320001e578ac")
            ],
            "name" : “meta 3"
        },
        {
            "_id" : "07544d96",
            "taskMetaDataIds" : [
                 ObjectId("5d55a648e2f732676676676”),
                 ObjectId("5d55a648e2612333556888”)
            ],
            "name" : “meta 2"
        },
        
    ],
    "name" : “New Topic",
    "createdBy" : "01526151-8303-450f-b08b-b36a1760b774",
    "createdDate" : ISODate("2019-09-15T16:52:36.150 0000"),
    "updatedDate" : ISODate("2019-09-15T16:52:36.150 0000")
}

I am looking for below output . Is there an operator which can directly convert the array of objects into array of strings as shown below. I can do it with a script by looping over the taskMetaDataIds array but I am looking to use a direct mongo operator which suits my purpose.

{
    "_id" : ObjectId("5d7e6c54c23c210001108556"),
    “parentId" : "5d0162ba69cf130001a16115",
    "tasks" : [
        {
            "_id" : "ae60a8f1",
            "taskMetaDataIds” : [
                "5d55a648e2f7320001e578ac"
            ],
            "name" : “meta 3"
        },
        {
            "_id" : "07544d96",
            "taskMetaDataIds" : [
                "5d55a648e2f732676676676”,
        “5d55a648e2612333556888”
            ],
            "name" : “meta 2"
        },
        
    ],
    "name" : “New Topic",
    "createdBy" : "01526151-8303-450f-b08b-b36a1760b774",
    "createdDate" : ISODate("2019-09-15T16:52:36.150 0000"),
    "updatedDate" : ISODate("2019-09-15T16:52:36.150 0000")
}

I tried below but it does not seem to be working-

db.getCollection("data").updateOne({"_id":ObjectId("5d7e6c54c23c210001108556")}, [{ $set: { "tasks.taskMetaDataIds": "$tasks.taskMetaDataIds.str" } }])

CodePudding user response:

  1. $set - Set tasks array field.

    1.1. $map - Iterate each element in the tasks array and return a new array.

    1.1.1. $mergeObjects - Merge the current iterated task object and taskMetaDataIds array (from the result 1.1.1.1).

    1.1.1.1. $map - Iterate the current iterated task object's taskMetaDataIds array and returns a new array.

    1.1.1.1.1. $toString - Convert each iterate id from ObjectId type to string type.

db.getCollection("data").updateOne({
  "_id": ObjectId("5d7e6c54c23c210001108556")
},
[
  {
    $set: {
      "tasks": {
        $map: {
          input: "$tasks",
          as: "task",
          in: {
            $mergeObjects: [
              "$$task",
              {
                "taskMetaDataIds": {
                  $map: {
                    input: "$$task.taskMetaDataIds",
                    in: {
                      $toString: "$$this"
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

Demo @ Mongo Playground

  • Related