Mongoose使用findByIdAndUpdate向数组推对象自动添加_id的原因排查
问题:使用Mongoose的findByIdAndUpdate推送数组对象时自动添加_id字段
在使用Mongoose的findByIdAndUpdate方法更新文档时,我向report数组中推送一个包含info和date的新对象,却发现每个推送的对象都会自动被添加_id字段。
实际生成的结构:
report: { info: 'abc', date: ..., _id: '123' }
预期的结构:
report: { info: 'abc', date: ... }
我的代码如下:
const productSchema = new mongoose.Schema({ name: { type: String, required: true }, hasReport: { type: Boolean }, // 如果没有报告则为空数组,有报告时向数组中推送新对象 report: [{ info: String, date: Date }], }) mongoose.model('Product', productSchema); updateProduct: async (req, res) => { const { id, hasReport, report: {info}} = req.body; const station = await Product.findByIdAndUpdate({_id: id}, { $push: { report: { info: info, date: new Date() }, }, $set: {hasReport: true}}) product.save() }
请问该现象的原因是什么?我的代码哪里存在问题?
解答
原因
Mongoose默认会为Schema中定义的嵌套对象(包括数组内的每个对象)自动生成_id字段,这是它的内置行为,目的是方便后续对子文档进行单独的查询、更新或删除操作。
解决方法
在定义report数组的子对象Schema时,添加_id: false配置,关闭自动生成_id的功能:
const productSchema = new mongoose.Schema({ name: { type: String, required: true }, hasReport: { type: Boolean }, report: [{ info: String, date: Date, _id: false // 关闭自动生成_id }], }) mongoose.model('Product', productSchema);
代码中的其他问题
- 冗余的
save()调用:findByIdAndUpdate方法本身会直接执行数据库更新操作,不需要再调用save(),且你这里变量名还写错了(用station接收结果,却调用product.save())。 - 解构赋值的潜在报错:如果请求体中没有
report字段,report: {info}的解构会抛出错误,建议添加默认值:
const { id, hasReport, report: {info} = {} } = req.body;
- 返回更新后的文档:默认情况下
findByIdAndUpdate返回的是更新前的文档,如果需要获取更新后的文档,需要添加{new: true}选项:
const station = await Product.findByIdAndUpdate( {_id: id}, { $push: { report: { info: info, date: new Date() }, }, $set: {hasReport: true} }, {new: true} // 添加此选项返回更新后的文档 )
内容的提问来源于stack exchange,提问作者user6377312
相关产品推荐
相关产品推荐

