Mongoose新增字段后执行save操作未更新文档如何解决
问题原因
Mongoose 基于 Schema 约束实现字段持久化逻辑,默认只会把 Schema 中明确定义的字段写入数据库。你当前的 UserSchema 没有声明 votedTimestamp 字段,直接给查询返回的文档实例赋值后调用 save,Mongoose 会自动忽略这个未定义字段的变更,不会同步到数据库。
解决方案
- 方案1:Schema 中补充字段定义(最推荐)
直接在UserSchema中新增votedTimestamp字段的声明,还可以直接配置默认值,后续不需要手动判断赋值,插入新文档时会自动填充:
const UserSchema = new mongoose.Schema({ userId: Number, wallet: Number, owningStock: Object, firstPrice: Object, owningItem: Object, // 新增字段定义 votedTimestamp: { type: Number, default: 0 } })
这种方式可以享受到 Mongoose 的字段类型校验、默认值填充等能力,也方便后续维护。
- 方案2:手动标记未定义字段的变更
如果只是临时需要新增字段、暂时不想修改 Schema,可以在赋值后调用markModified()方法手动告诉 Mongoose 该字段发生了变更,需要被持久化:
User.findOne({userId : userId}) .then(user => { if(user.votedTimestamp == undefined){ user.votedTimestamp = 0; // 手动标记字段变更 user.markModified('votedTimestamp') user.save() } })
- 方案3:直接调用更新接口写入
绕过文档实例的变更检测,直接用findOneAndUpdate搭配$set操作符写入字段,未在 Schema 中定义的字段也能成功写入数据库:
User.findOneAndUpdate( { userId: userId, votedTimestamp: { $exists: false } }, { $set: { votedTimestamp: 0 } }, { new: true } // 配置后返回更新后的文档 ).then(updatedUser => { // 后续业务逻辑 })
注意如果后续需要从查询返回的 Mongoose 文档实例中读取该未定义字段,需要在查询时加 lean() 方法将文档转为普通 JS 对象,或者还是在 Schema 中补充字段定义。
内容的提问来源于stack exchange,提问作者Nyaco
相关产品推荐
相关产品推荐

