如何在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
相关产品推荐
相关产品推荐

