Mongoose Aggregate on an Embedded/Nested Documents

I have this users and posts collection with embedded docs comments and replies:

  1. users
{
 _id:34
 name:"Palestine"
}
  1. Posts
{
 _id:"1234",
 body:" hello ! I love mongodb, but its hard",
 likes:["34"],
 comments:{
    _id:"3453",
    body:"me I don't like mongodb i like sql "
    likes:["34"],
    replies:{
       _id:"2345",
       body:"both of them are great"
       likes:["34"],
    }
  }
}

The question is that, i want to aggregate into the posts and get all the them, after that i want to append new key value to both post, comments, replies, witch gonna specify if the user liked the post or not ex: liked:true
Note: I have the authenticated user id ready . I want check if the user Id exist in the likes docs on each sub trees (posts, comments, replies )

To be more specific about this question this is my expected humble result :

{
 _id:"1234",
 body:" hello ! I love mongodb, but its hard",
 liked:true,
 likesCount:1
 comments:{
     _id:"3453",
     body:"me I don't like mongodb i like sql "
     liked:true,
     likesCount:1
     replies:{
       _id:"2345",
       body:"both of them are great"
       liked:true,
       likesCount:1
    }
  }
}

Note : If you can help to query upto the comments its okay for me :
Result expected :

{
 _id:"1234",
 body:" hello ! I love mongodb, but its hard",
 liked:true,
 likesCount:1
 comments:{
     _id:"3453",
     body:"me I don't like mongodb i like sql "
     liked:true,
     likesCount:1
  }
}

This is what I tried :

const result = await PostModel.aggregate([
      {
        $project: {
          likesCount: { $size: "$likes" },
          commentsCount: { $size: "$comments" },
          liked: { $in: [ID(uid), "$likes"] },
          likes: 1,
            ||
            ||
            \/
Note: i dont know if i need to `$group` first or `$unwind`
      ................................................
     }
}

…
I have a hard time finding how to perform the next step

First… There are some fundamental problems with your query.

const result = await PostModel.aggregate([
      {
        $project: {
          likesCount: { $size: "$likes" },
          commentsCount: { $size: "$comments" },
          liked: { $in: [ID(uid), "$likes"] },
          likes: 1,
            ||
            ||
            \/
Note: i dont know if i need to `$group` first or `$unwind`
      ................................................
     }

Why are you using “const” as your variable? This should be var in my opinion cause const (constant) implies that the result will not change…

Second…
Ensure your references are to actual fields. I see that you are projecting the field “likes” into “likesCount” but I do not see a “likes” field in your schema.

Third… Ensure that you properly reference the ID field. If you want an object ID you must use “_id” not ID(uid). If you don’t want to pass the object ID to the projection, then you need to create a separate ID field and reference it there.

As for the other commands… It depends on what your working with… If you are using arrays… You may have to $map them to modify any data in them… Hopefully this helps…

As far as $unwind, and $group… I don’t know if you are getting the result you expect from the query.

1 Like