Search code examples
mongodbmern

Editing specific element of an array of a particular collection - mongoDb


I am new to mongoDb. I have created a collection named task that has comments field which is array along with other fields. I need to edit specific comment of the task. There is a edit button in each comment. Both task id and comment id are available. Now how to edit specific comment of the task?

Thanks in advance

task api

{
   "status":true,
   "task":[
      {
         "_id":"61dfef323a6ee474c4eba926",
         "description":"hello there",
         "title":"hello",
         "comments":[
              {
                 "comment_id":1,
                 "username":"test",
                 "comment":"abcd",
                 "status":true,
              }, 
              {
                "comment_id":2,
                 "username":"test",
                 "comment":"abcdsdfsdf",
                 "status":true,
              }
           ],
         "createdAt":"2022-01-13T09:21:54.795Z",
         "updatedAt":"2022-01-13T09:21:54.795Z",
         "__v":0
      }
   ]
}

Task model schema

const taskSchema = new Schema({
  title: { type: String, required: true },
  description: { type: String, required: true },
  comments: [Object],
}, {
  timestamps: true,
});

I tried using $set but I don't know how to use it in the inner array.

router.route('./comments/edit').post((req, res) => {
  const commentId = req.body.commentId;
  const taskId = req.body.postId;

  const comment = req.body.editedComment;
  const updatedAt = new Date();

  Task.updateOne(
    { _id: taskId},
    {
     //what to do here?
    //   $set: { comments: [ {'comment_id': commentId} ]},
    }
  )
    .then((response) => res.json({ status: true, msg: 'Comment Edited!' }))
    .catch(err => res.json({ status: false, msg: err }));
});

Thanks in advance.


Solution

  • This is how to do best:

      db.collection.update({
      status: true
      },
      {
       $set: {
      "task.$[x].comments.$[y].username": "New Name"
     }
    },
    {
      arrayFilters: [
      {
        "x._id": "61dfef323a6ee474c4eba926"
       },
       {
        "y.comment_id": 2
       }
      ]
     })
    

    Explained:

    1. Define x and y as arrayFIlters in the update statement.
    2. In the $set statement provide the x & y filters to identify the specific comment for update.

    In the example I update the username , but you can update any other value from the targeted array subelement addressed by x & y.

    playground

    And here is how to update two values at same time in the same nested array element.