Mongoose调用.save()方法时__v版本号未自动递增问题咨询
Mongoose调用save()时__v字段不自动递增的原因及解决方案
问题原因
- 默认行为设计:Mongoose 5.x版本的默认逻辑中,
__v版本键仅在修改数组类型字段时才会自动递增,修改字符串、日期、数字等标量类型字段不会触发自动递增逻辑,这就是你日志里看不到$inc操作符的核心原因。 - 配置关闭版本键:如果Schema定义时设置了
{ versionKey: false },或者调用save方法时传入了{ versionKey: false }参数,也会导致__v不会更新。
解决方案
方案1:开启乐观并发控制(推荐)
如果需要同时实现并发修改防冲突,以及所有修改操作都自动递增__v,可以在Schema定义时开启optimisticConcurrency配置:
const deviceSchema = new mongoose.Schema({ name: String, updatedAt: Date, // 其余字段定义 }, { optimisticConcurrency: true, // 开启乐观并发 versionKey: '__v' // 确保版本键启用,默认值即为__v可省略 });
开启后所有save操作都会自动携带$inc: { __v: 1 }逻辑,当并发修改导致版本不匹配时会抛出VersionError,避免脏写。如果开启后不生效,请将Mongoose升级到5.10.0及以上版本,该特性在此版本后正式稳定可用。
方案2:使用pre('save')中间件自动递增
如果不需要乐观并发控制,只需要所有修改都自动递增__v,可以给对应Schema添加pre保存中间件:
deviceSchema.pre('save', function(next) { this.increment(); // Mongoose内置方法,自动给版本键+1 next(); });
方案3:单次修改手动递增
如果只有个别场景需要递增__v,可以在调用save方法前手动修改版本值:
device.name = 'New Name'; device.updatedAt = new Date(); device.__v += 1; // 手动给版本号+1 const result = await device.save();
内容的提问来源于stack exchange,提问作者Chicky
相关产品推荐
相关产品推荐

