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

如何在Mongoose中为reply数组内的元素自动生成ObjectId

解决方法

你只需要修改两部分代码,分别是Schema定义和业务逻辑代码:

步骤1:调整评论Schema,将reply定义为结构化子文档数组

原来的reply字段被定义为无结构的普通Array,Mongoose不会对其内部元素做任何自动处理,你需要明确声明reply的子Schema,配置自动生成ObjectId的逻辑:

const mongoose = require('mongoose');
const validator = require('validator');

// 新增回复子Schema,配置自动生成id字段
const replySchema = new mongoose.Schema({
  id: {
    type: mongoose.Schema.Types.ObjectId,
    default: () => new mongoose.Types.ObjectId() // 新增回复时自动生成ObjectId
  },
  userID: {
    type: mongoose.Schema.Types.ObjectId,
    required: true
  },
  name: String,
  avatar: String,
  content: {
    type: String,
    required: [true, 'Please enter your content'],
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
})

const commentSchema = new mongoose.Schema({
  course: {
    type: mongoose.Schema.Types.ObjectId,
    required: true,
    ref: 'Course',
  },
  comments: [
    {
      id: {
        type: mongoose.Schema.Types.ObjectId,
      },
      name: {
        type: String,
      },
      avatar: {
        type: String,
      },
      content: {
        type: String,
        required: [true, 'Please enter your content'],
      },
      // 把原来的Array类型替换为子文档数组
      reply: { type: [replySchema], default: [] },
      createdAt: {
        type: Date,
        default: Date.now,
      },
      updatedAt: {
        type: Date,
        default: Date.now,
      },
    },
  ],
});

module.exports =
  mongoose.models.Comment || mongoose.model('Comment', commentSchema);

步骤2:修改保存回复的业务代码

首先修改传入的reply数据结构,把原来的id字段改为userID(对应你期望的结构),另外删除多余的重复save调用:

const replyComment = catchAsyncError(async (req, res, next) => {
  const commentModel = await Comment.findOne({ course: req.query.courseId });

  if (!commentModel) {
    return next(new ErrorHandler('Invalid course', 400));
  }

  const commentIndex = commentModel.comments.findIndex(
    (comment) => comment._id == req.query.commentId
  );

  if (commentIndex === -1) {
    return next(
      new ErrorHandler('No comments of the course was found with this ID', 400)
    );
  }
  console.log(commentModel.comments[commentIndex]);

  const data = {
    // 原来的id字段改为userID,存储当前用户的id
    userID: req.user._id,
    name: req.user.name,
    avatar: req.user.avatar.url,
    content: req.body.content,
  };
  let commentAfterSaved = null;

  commentModel.comments[commentIndex].reply.push(data);
  await commentModel.save().then((comments) => {
    commentAfterSaved =
      comments.comments[commentIndex].reply[
        comments.comments[commentIndex].reply.length - 1
      ];
  });

  return res.status(200).json({
    success: true,
    comment: commentAfterSaved,
  });
});

补充说明

如果你不需要自定义id字段,也可以直接使用Mongoose子文档默认的_id字段,无需在replySchema中手动声明id,Mongoose会自动为每个子文档生成唯一的_id,符合你需要的唯一标识需求。


内容的提问来源于stack exchange,提问作者An in real life

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:15:03