[MONGOOSE] parent‐child comment relationships with count - fourslickz/notes GitHub Wiki

import mongoose, { Schema } from 'mongoose';

const CommentSchema = new Schema({
  content: { type: String, required: true },
  author: { type: String, required: true },
  postId: { type: Schema.Types.ObjectId, ref: 'Post', required: true },
  parentComment: { type: Schema.Types.ObjectId, ref: 'Comment', default: null }, // Parent comment if it's a reply
  createdAt: { type: Date, default: Date.now },
});

const Comment = mongoose.model('Comment', CommentSchema);
export { Comment };

async function getPostCommentsWithChildCount(postId: string) {
  const comments = await Comment.aggregate([
    // Step 1: Match comments belonging to a specific post
    {
      $match: {
        postId: new mongoose.Types.ObjectId(postId),
        parentComment: null, // Only match root (parent) comments
      },
    },
    // Step 2: Lookup child comments (replies)
    {
      $lookup: {
        from: 'comments', // Lookup from the same collection
        localField: '_id', // Parent comment ID
        foreignField: 'parentComment', // Match child comments by parentComment field
        as: 'childComments', // The result will be stored in this field
      },
    },
    // Step 3: Add a field `childCount` with the number of child comments
    {
      $addFields: {
        childCount: { $size: '$childComments' }, // Count the number of child comments
      },
    },
    // Step 4: Project the fields to return
    {
      $project: {
        content: 1,
        author: 1,
        childCount: 1, // Include the childCount
        childComments: { content: 1, author: 1, createdAt: 1 }, // Include specific fields from child comments
      },
    },
  ]);

  console.log(comments);
  return comments;
}

// Example usage:
getPostCommentsWithChildCount('your-post-id-here');