Update an object in nested array in MongoDB

Rajesh Royal - Sep 28 '21 - - Dev Community

Hello Reader 👋

To update an object inside a nested array in MongoDB you can use this approach, Its well tested and working.

Case:

Update nested array objects. See below picture for a better Idea what we are going to do. We will update the object which is nested by 3 levels of array.

{
 discussionList[
  discussionList [
   {
     object-value-to-be-updated.
   }
  ]
 ]
} 
Enter fullscreen mode Exit fullscreen mode

mongodb - update an object inside multilevel nested array

Solution:

public courseCategoryPostCommentReplyUpdate(operation: CommentReplyUpdateMutation): Promise<IDocumentUpdateType> {
    return this.courseCategoryPostCommentsModel.updateOne(
      {
        "postId" : operation.postId,
        'discussionList': {
          '$elemMatch': {
            '_id': operation.commentId,
            "discussionList._id": operation.replyId
          }
        }
      },
      {
        $set: {
          "discussionList.$[outer].discussionList.$[inner].payload": operation.payload,
          "discussionList.$[outer].discussionList.$[inner].isUpdated": true,
          "discussionList.$[outer].discussionList.$[inner].commentUpdateTime": new Date()
        }
      },
      {
        arrayFilters: [
          { "outer._id": operation.commentId},
          {"inner._id": operation.replyId}

      ]
      }
    );
  }
Enter fullscreen mode Exit fullscreen mode

FootNotes - this code is to update the reply of a comment.

That's how you can perform operations on an object in nested array in mongoDB document. You can also update/delete the objects which are having the more level of nesting by just modifying the query.

Example of delete and get

Delete
// Informational Note:
  // Delete nested array values in mongodb


  public courseCategoryPostCommentReplyDelete(operation: CommentReplyDeleteMutation): Promise<IDocumentUpdateType> {
    return this.courseCategoryPostCommentsModel.updateOne(
      {
        'postId': operation.postId,

        'discussionList': {
          '$elemMatch': {
            '_id': operation.commentId,
            'discussionList._id': operation.replyId
          }
        }
      }, {
        $pull: {
          'discussionList.$[outer].discussionList': {
            user: operation.userId,
            _id: operation.replyId
          }
        }
      },
      {
        arrayFilters: [
          { 'outer._id': operation.commentId }
        ],
        multi: false
      }
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

GET

public courseCategoryPostCommentRead(postId: string): Promise<IComment> {
    return this.courseCategoryPostCommentsModel.findOne<IComment>({
      postId: postId
    }).populate('discussionList.user').populate('discussionList.discussionList.user').exec();
  }
Enter fullscreen mode Exit fullscreen mode

I was using GraphQL. You may need to iterate over the result and show the comments/replies as per that.

Please let me know if the code needs an explanation. Thanks 🙂

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player