You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mongoose中查询父子引用评论,将回复ID转为数组返回?

两种实现方案:虚拟属性 & 聚合框架

一、用虚拟属性实现

直接在你的Schema中定义虚拟属性,反向关联所有回复当前评论的子评论ID:

const commentSchema = new Schema(
  {
    content: String,
    score: Number,
    replyingTo: { type: mongoose.Types.ObjectId, ref: "Comment" },
  },
  // 开启虚拟属性的序列化支持,否则查询结果里不会显示
  { toJSON: { virtuals: true }, toObject: { virtuals: true } }
);

// 定义replies虚拟属性,获取所有以当前评论为父级的子评论ID
commentSchema.virtual('replies', {
  ref: 'Comment',
  localField: '_id',       // 当前评论的ID
  foreignField: 'replyingTo', // 子评论中指向父级的字段
  justOne: false,          // 返回数组而非单个文档
  // 转换结果,只保留子评论的ID
  transform: (docs) => docs.map(doc => doc._id.toString())
});

const Comment = mongoose.model("Comment", commentSchema);

查询时需要通过populate加载虚拟属性:

// 查询单个评论并加载其回复ID数组
const targetComment = await Comment.findById(yourCommentId).populate('replies');
// 此时targetComment.replies就是你需要的ID数组

二、用聚合框架实现

如果不想修改Schema,可以直接通过聚合管道在查询时生成目标格式:

const formattedComments = await Comment.aggregate([
  // 关联所有回复当前评论的子评论
  {
    $lookup: {
      from: 'comments', // 注意:mongoose默认集合名为模型名的小写复数
      localField: '_id',
      foreignField: 'replyingTo',
      as: 'replies'
    }
  },
  // 将关联结果转换为仅包含ID的数组
  {
    $project: {
      content: 1,
      score: 1,
      replies: { $map: { input: '$replies', as: 'item', in: '$$item._id' } }
    }
  }
]);

执行后返回的formattedComments数组中,每个对象都会包含replies字段,格式完全符合你的需求。

内容的提问来源于stack exchange,提问作者sasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:57:21