Change string to object with string data

I have a collection like this

[
{
    _id: ObjectId("62aafb10e9123be010871280"),
    task_id: ObjectId("62aad470a743c5d36362fc2f"),
    comments: [
      {
        user_id: ObjectId("627e4b14c35e9de228efe63b"),
        comment: "Tested this feature in Staging and it's working as expected",
        _id: ObjectId("62aafb10a743c5d3636303c5"),
        created_at: ISODate("2022-06-16T09:42:40.619Z")
      }
    ]
  },
  {
    _id: ObjectId("62aafbafe9123be0108712ed"),
    task_id: ObjectId("62aafb5da743c5d3636303d8"),
    comments: [
      {
        user_id: ObjectId("627e4b14c35e9de228efe63b"),
        comment: "Tested this feature in staging and it's working as expected",
        _id: ObjectId("62aafbafa743c5d363630413"),
        created_at: ISODate("2022-06-16T09:45:19.732Z")
      }
    ]
  },
]

and I want to make it like this

[
{
    _id: ObjectId("62aafb10e9123be010871280"),
    project_id: ObjectId("6279fbd969d9ec50ca2e274a"),
    task_id: ObjectId("62aad470a743c5d36362fc2f"),
    __v: 0,
    comments: [
      {
        user_id: ObjectId("627e4b14c35e9de228efe63b"),
         comment: {markup: "Tested this feature in staging and it's working as expected", text: "Tested this feature in staging and it's working as expected"},
        _id: ObjectId("62aafb10a743c5d3636303c5"),
        created_at: ISODate("2022-06-16T09:42:40.619Z")
      }
    ]
  },
  {
    _id: ObjectId("62aafbafe9123be0108712ed"),
    project_id: ObjectId("6279fbd969d9ec50ca2e274a"),
    task_id: ObjectId("62aafb5da743c5d3636303d8"),
    __v: 0,
    comments: [
      {
        user_id: ObjectId("627e4b14c35e9de228efe63b"),
        comment: {markup: "Tested this feature in staging and it's working as expected", text: "Tested this feature in staging and it's working as expected"},
        _id: ObjectId("62aafbafa743c5d363630413"),
        created_at: ISODate("2022-06-16T09:45:19.732Z")
      }
    ]
  },
]

I am not an expert. This may be a start. I am adding first the approach that didn’t work as well, because that is how I like to be explained.

Using $set

See code
db.collection.update({ }, /* <---- selects all docs */
{
  "$set": {/* think of it as "add a field" */
    "comments.$[].comment": {
      "key": "value" /* Unable to use $$ stuff */
    }
  }
},
{
  multi: true /* enable multiple updates */
})

Using pipeline

After thinking a bit more I realized that we want to map the old array to new array. We can use all this tooling in a pipeline.

A pipeline of a single stage isn’t great but this will allow to run a $map, and also using $mergeObjects. These two are powerful tools.

See Code
db.collection.update({},
[
  {
    "$addFields": {
      "comments": { /* will add this field i.e overwrite it */ 
        "$map": {
          input: "$comments",// select the field we map over (so here we have the array)
          as: "c",//name for the current item, could be "thiscomment" or anything else.
          in: {//trick comes below, we merge 2 objects (current item "comment" gets overwritten)
            "$mergeObjects": [
              "$$c",
              {
                "comment": {
                  "markup": "$$c.comment",
                  "text": "$$c.comment"
                }
              }
            ]
          }
        }
      }
    }
  }
],
{
  multi: true// modifies all matched docs (all in this case)
})
1 Like

this doesn’t solve my problem, I want the values of the comment which are “Tested this feature in staging and it’s working as expected” (these are dynamic values to different docs), to be in a new object like ({markup"Tested this feature in staging and it’s working as expected"})

i came up with this db.comments.find({comments:{"$ne":[]}}).forEach(function(a){ a.comments.forEach(function (b,i){b.comment = b.comment.replace(b.comment,{"markup":b.comment, "text":b.comment}) })}) but no use

Did you click on the second link that I included ? i.e Mongo playground

Sorry, I missed the second link, it worked.

Thank You santimir.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.