'MongoDB Mongoose Add field to a populated objects

I'm writing an API and I wanted to add a new field in my query that'll indicate if the Comment object was made by the user making a request.

On my Comment Schema, I have a field that indicates the owner of the comment:

const CommentSchema: Schema = new mongoose.Schema<CommentType>({
  createdBy: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
})

On my controller, I first aggregated adding another field I needed, and then I populate it to get the Comment objects:

const user = await User.findById(req.userId)
const postQuery = await Post.aggregate()
    .addFields({ likedByUser: { $in: ['$_id', user.likedPosts] } })
    .match({ _id: new mongoose.Types.ObjectId(req.params.postId) })
    .project({ createdBy: 0, location: 0, createdAt: 0, __v: 0 })

await Post.populate(postQuery, {
    path: 'comments',
    select: { _id: 1, text: 1 }
})

At this point, I'm getting the correct data, but I wanted to add a field in each comment that will be true if the comment was made by the user and false otherwise, without having to loop over the results array I already have as this might get big, so not very efficient. I thought maybe even my populate could be done somehow only by the aggregate, that way it would be even more eficient I would say. Is that even possible?



Solution 1:[1]

In the end, I solved it by using a lookup.

const postQuery = await Post.aggregate()
.match({ _id: new mongoose.Types.ObjectId(req.params.postId) })
.lookup({
    from: 'comments',
    localField: 'comments',
    foreignField: '_id',
    as: 'commentsUnwided'
})
.addFields({ likedByUser: { $in: ['$_id', user.likedPosts] } })
.project({
    text: 1,
    colorCode: 1,
    city: 1,
    likeAmount: 1,
    comments: {
        $map: {
            input: '$commentsUnwided',
            as: 'comment',
            in: {
                id: '$$comment._id',
                text: '$$comment.text',
                createdByUser: {
                    $eq: ['$$comment.createdBy', userId]
                }
            }
        }
    }
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Luc