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.
}
]
]
}
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}
]
}
);
}
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
}
);
}
}
GET
public courseCategoryPostCommentRead(postId: string): Promise<IComment> {
return this.courseCategoryPostCommentsModel.findOne<IComment>({
postId: postId
}).populate('discussionList.user').populate('discussionList.discussionList.user').exec();
}
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 π
Top comments (6)
how can I use pull in this? I tried modifying the query but it prompts me up with errors like, pull to a non array value further modifying it gives me, Could not find path "undefined.0.userId" in schema.
@linkitsoftoffice I have updated the post.
Data :
Query
Output
MongoServerError: No array filter found for identifier 'outer' in path 'playlists.$[outer].musics.$[inner].duration'
Please help to correct the error
where do we get the inner and outer variables?
You don't have to get those variables.
The inner and outer variables are used as placeholders. If you see in the arrayFilter we are modifying the ._id part of these variables.
found the issue $arrayFilters , it should be arrayFilters