乐闻世界logo
搜索文章和话题

Mongoose 中的 __v 字段的作用是什么?

9 个月前提问
5 个月前修改
浏览次数120

6个答案

1
2
3
4
5
6

Mongoose 中的 __v 字段是一个隐藏字段,它代表了文档的版本号。这个字段由 Mongoose 在内部使用,主要目的是为了支持文档的版本控制,使用乐观锁定机制来避免并发修改时的冲突。

每当在 Mongoose 中创建或保存文档时,如果该文档包含数组字段,并且执行了会修改数组的操作(例如,添加或删除元素),Mongoose 会自动更新这个 __v 字段的值。这样,当多个用户或进程同时尝试修改同一文档时,Mongoose 可以通过检查 __v 字段的值来确定文档是否已经被其他方修改过,从而决定是否允许当前的修改操作继续执行。

这个版本号是自动维护的,开发者通常不需要手动修改它。当然,如果不需要这个字段,也可以在定义 Mongoose Schema 时通过选项 { versionKey: false } 禁用它。

例如,如果我们定义一个简单的用户模型,并希望禁用 __v 字段,我们可以这样做:

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const userSchema = new Schema({ name: String, email: String, password: String }, { versionKey: false }); // 禁用 __v 字段 const User = mongoose.model('User', userSchema);

但在大多数情况下,开发者都保留这个字段,以便可以利用其提供的并发修改控制的功能。

2024年6月29日 12:07 回复

这里

versionKey是 Mongoose 首次创建每个文档时设置的属性。该键值包含文档的内部修订。该文档属性的名称是可配置的。默认为__v.

如果这与您的应用程序冲突,您可以这样配置:

shell
new Schema({..}, { versionKey: '_somethingElse' })
2024年6月29日 12:07 回复

好吧,我看不到托尼的解决方案……所以我必须自己处理……


如果您不需要 version_key,您可以:

shell
var UserSchema = new mongoose.Schema({ nickname: String, reg_time: {type: Date, default: Date.now} }, { versionKey: false // You should be aware of the outcome after set to false });

将 versionKey 设置为 false 意味着文档不再受版本控制。

如果文档包含子文档数组,则会出现问题。可以删除其中一个子文档,从而减小数组的大小。稍后,另一个操作可以访问数组中原始位置的子文档。

由于数组现在较小,因此可能会意外访问数组中的错误子文档。

versionKey 通过将文档与 versionKey 相关联来解决这个问题,mongoose 在内部使用 versionKey 来确保它访问正确的集合版本。

更多信息请访问:http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html

2024年6月29日 12:07 回复

要在 NestJS 中删除,需要向Schema()装饰器添加选项

shell
@Schema({ versionKey: false })
2024年6月29日 12:07 回复

如果不需要,可以禁用版本密钥。

看这个例子:

shell
var User = new mongoose.Schema({ FullName:{ type :String, }, BirthDay:{ type :String, }, Address:{ type :String, }, Gender:{ type:String, }, PhoneNumber:{ type:Number, ref:'Account' }, AccountID:{ type: Schema.Types.ObjectId, ref: 'Account' }, UserName:{ type:String, ref:'Account' } },{collection:'User', versionKey: false //here });
2024年6月29日 12:07 回复

我们“文档”中的“__v”字段服务于“ **optimisticConcurrency”**问题。

这个术语在 mongoose 中基本上意味着:让您通过“findOne, findById”抓取文档,但尚未使用 mongoose 的 save() 方法。如果在此时间间隔内,任何其他代码获取相同的文档并在第一个文档实例之前使用 .save() 方法,该怎么办?在这个用例中,如果我们想(特定于猫鼬)抛出版本错误之类的事情,我们optimisticConcurrency: true在模式中使用选项。

然后 mongoose 将使用 '__v1' 来比较这两个文档。

没有optimisticConcurrency: true选择。'__v' 没有效果。并且 mongoose 不会将其增加 1。

注意:在“findOneAndUpdate”类似操作中,不会更新“__v”。(仅 save() 更新)

2024年6月29日 12:07 回复

你的答案