如何在Mongoose findOneAndUpdate中将字段值设为undefined?
问题
我的Mongoose Schema定义如下:
({ name: { type: String, required: true, }, color: { type: String, }, createdAt: { type: Date, default: Date.now, }, });
其中name为必填字段,color为可选字段。用户创建的初始文档如下:
{ "name": "Blue", "color": "#20387d" }
当用户编辑文档时未提供color值,请求体为:
{ "name": "Blue" }
我的更新代码如下:
const { name, color} = req.body; const document = await Model.findOneAndUpdate( { _id: req.params.id, }, { $set: { name, color }}, { new: true } );
期望此时MongoDB中的color值被更新为undefined,但实际color仍保留初始值,仅name字段被更新。需要实现:当用户未提供color值时,将其设为undefined,该如何操作?
解决方案
问题核心是Mongoose会自动忽略$set中的undefined字段,所以当color从无color的请求体中解构出来为undefined时,数据库不会执行该字段的更新操作。可以通过以下方式实现需求:
方法1:手动构建更新对象,显式处理color
通过严格判断请求体中是否存在color字段,决定是否将其显式设置为undefined(MongoDB最终会存储为null):
const { name } = req.body; const updateData = { name }; // 用'in'运算符判断,避免空字符串等合法值被误处理 if (!('color' in req.body)) { updateData.color = undefined; } else { updateData.color = req.body.color; } const document = await Model.findOneAndUpdate( { _id: req.params.id }, { $set: updateData }, { new: true } );
方法2:使用空值合并运算符简化赋值
利用ES6的空值合并运算符??,直接为color赋值,当请求体中无color时设为undefined:
const updateData = { name: req.body.name, color: req.body.color ?? undefined }; const document = await Model.findOneAndUpdate( { _id: req.params.id }, { $set: updateData }, { new: true } );
注意:MongoDB本身不支持存储
undefined类型,Mongoose会自动将undefined转换为null存储。如果需求是直接删除color字段而非设为null,可以改用$unset操作:
const updateOps = { $set: { name: req.body.name } }; if (!('color' in req.body)) { updateOps.$unset = { color: "" }; } const document = await Model.findOneAndUpdate( { _id: req.params.id }, updateOps, { new: true } );
内容的提问来源于stack exchange,提问作者SunAns
相关产品推荐
相关产品推荐

