MongoDB使用findOneAndUpdate添加不存在新字段失败求助
MongoDB findOneAndUpdate 未新增loginDate字段排查
问题描述
尝试在用户每次登录时通过findOneAndUpdate的$push操作,为不存在的loginDate字段添加数据,但数据库未新增该字段。
代码示例
const userLog = await User.findOneAndUpdate( { NIK: req.body.NIK }, // { loginDate: { $exists: false } }, { $push: { loginDate: toJSONLocal(date) } }, { new: true } ); console.log("===================================="); console.log(userLog); console.log("====================================");
返回结果
_id: new ObjectId("6368e40d1f58fd76efb27957"), fullname: 'Ja lie', password: '$2b$10$DEWgxY/hth/yYIVGOvZDt..RpxKCKm58NbrrDFQgITLB8.cHrHHvG', NIK: 'MT220', status: 'active', department: 'Logistic', position: 'Trainee', Group_Shift: 'Non Shift', role: 'admin', createdAt: 1667818509, updatedAt: 1669188767, __v: 0
排查原因
$push操作仅对已存在的数组字段生效,若目标字段不存在,MongoDB默认不会自动创建该字段。- Mongoose默认开启
strict模式(值为true),如果User模型的Schema未声明loginDate字段,Mongoose会过滤掉未定义字段的更新操作。
解决方案
方案1:修改Schema添加loginDate字段(推荐)
在User模型的Schema中明确声明loginDate为数组类型,确保Mongoose允许该字段的更新:
const userSchema = new mongoose.Schema({ // 保留原有字段定义... loginDate: { type: [Date], // 若toJSONLocal返回字符串则改为[String] default: [] // 初始化为空数组,确保$push能正常工作 } }); const User = mongoose.model('User', userSchema);
方案2:临时关闭strict模式(不推荐长期使用)
如果不想修改Schema,可在findOneAndUpdate的选项中添加strict: false,允许更新未在Schema中定义的字段:
const userLog = await User.findOneAndUpdate( { NIK: req.body.NIK }, { $push: { loginDate: toJSONLocal(date) } }, { new: true, strict: false } );
方案3:改用$addToSet(避免重复登录记录)
如果需要防止同一登录日期被重复添加,可替换$push为$addToSet,同时确保字段存在或Schema允许:
const userLog = await User.findOneAndUpdate( { NIK: req.body.NIK }, { $addToSet: { loginDate: toJSONLocal(date) } }, { new: true } );
验证方式
修改后重新触发登录逻辑,检查控制台输出的userLog是否包含loginDate字段,同时直接查看MongoDB数据库中的对应文档,确认字段已新增并包含数据。
内容的提问来源于stack exchange,提问作者JS24
相关产品推荐
相关产品推荐

