Mongoose设_id:false报document must have an _id解决
Mongoose保存报"document must have an _id before saving"问题解决方案
问题复现
创建文档逻辑
// create the document --------------- const id = mongoose.Types.ObjectId() let userDoc = await Admin.create({ ...req.body, _id: id, by: id })
Schema定义
adminSchema = new mongoose.Schema({ // 其余字段含firstName、lastName等 by: { type: mongoose.Schema.ObjectId, ref: 'Admin', required: [true, "the 'by' field is required"], immutable: true, } }, { _id: false })
Model定义
const Admin = mongoose.model('Admin', adminSchema, 'users')
- 当前Schema未显式定义
_id属性 - 预期效果:文档
_id与by字段取同一个服务端生成的ObjectId - 实际报错:
Error: MongooseError: document must have an _id before saving at .../node_modules/mongoose/lib/model.js:291:18
问题根因
报错由Schema配置项{ _id: false }触发。该配置的作用是告知Mongoose不要自动为文档生成、维护_id字段,会直接阻断Mongoose默认的_id校验、赋值逻辑,即使手动传入_id值也不会被识别为合法的文档主键。
最初配置该选项的目的是让接口返回给客户端的响应中隐藏_id字段,但这个配置属于文档存储层规则,和接口返回的字段序列化逻辑完全无关,混用就会导致保存异常。
解决方案
推荐方案:拆分存储配置和返回序列化配置
- 移除Schema中的
{ _id: false }配置,让Mongoose正常处理_id主键的逻辑,原有手动生成id、给_id和by赋同值的代码不需要修改,即可正常保存文档。 - 单独配置接口返回的字段过滤规则,实现隐藏
_id的需求,两种常用实现:- 全局配置(所有接口返回该Model数据时自动隐藏
_id):在Schema中添加toJSON转换规则adminSchema = new mongoose.Schema({ // 其余字段含firstName、lastName等 by: { type: mongoose.Schema.ObjectId, ref: 'Admin', required: [true, "the 'by' field is required"], immutable: true, } }, { toJSON: { transform: (doc, ret) => { delete ret._id delete ret.__v // 可同步移除版本号字段 return ret } } }) - 单接口配置(仅在特定接口隐藏
_id):返回响应前手动解构过滤字段const { _id, ...respData } = userDoc.toObject() return res.json(respData)
- 全局配置(所有接口返回该Model数据时自动隐藏
备选方案:显式声明_id字段保留_id: false配置
如果有特殊场景必须保留{ _id: false }配置,需要在Schema中显式定义_id字段,让Mongoose识别该主键:
adminSchema = new mongoose.Schema({ _id: { type: mongoose.Schema.ObjectId, required: true }, // 其余字段含firstName、lastName等 by: { type: mongoose.Schema.ObjectId, ref: 'Admin', required: [true, "the 'by' field is required"], immutable: true, } }, { _id: false })
该方案同样可以解决保存报错问题,后续隐藏_id的返回逻辑和上述推荐方案一致。
注意:存储层配置和接口返回序列化逻辑要拆分处理,不要为了调整返回字段去修改MongoDB文档的主键规则,否则很容易触发这类底层保存异常。
内容的提问来源于stack exchange,提问作者Islam Y-
相关产品推荐
相关产品推荐

