Mongoose中的"__v"字段是什么?

429
我正在使用版本为3的Mongoose和版本为2.2的MongoDB。我注意到我的MongoDB文档中开始出现一个名为__v的字段。这与版本控制有关吗?它的用途是什么?

如果你不想在结果中包含它,可以在mongoose返回的对象上使用_doc。 - moein rahimi
9个回答

415

这里得知:

versionKey是由Mongoose在创建文档时设置的属性。它的值包含了文档的内部版本信息。此文档属性的名称是可配置的,默认值为__v

如果该名称与您的应用程序冲突,则可以进行如下配置:

new Schema({..}, { versionKey: '_somethingElse' })

34
使用这个属性来确定一个文档是否刚刚被创建(例如,__v === 0)是安全的吗? - Explosion Pills
69
供日后参考:不。版本号仅在可能导致冲突的操作(修改数组位置)之后递增。其他更新不会递增版本号。原始发布帖详细解释了这一点:http://aaronheckmann.tumblr.com/post/48943525537/mongoose-v3-part-1-versioning - Ricardo Tomasi
4
有没有一种方法可以在查询返回的文档中隐藏它? - Diosney
11
@diosney query.select('-__v') 的意思是查询时不包含 "__v" 这个字段。@ExplosionPills 你需要添加 Mongoose 中间件,比如 schema.pre('save', function(next) { this.increment(); next(); })。这段代码的作用是在保存数据前自增一个计数器。 - wprl
4
@talentedmrjones @wprl 这正是我现在正在做的事情,但我想要一个可以直接放入模式中的东西,以便在所有查询中使用。 - Diosney
显示剩余3条评论

105

好的,我看不到Tony的解决方案...所以我必须自己处理...


如果你不需要version_key,你可以这样做:

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内部使用它确保它访问正确的集合版本。更多信息请参见:http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html

39
将其设置为false的结果是什么? - xperator
5
و‚¨è؟کهڈ¯ن»¥è°ƒç”¨resultFromMongo.toObject({ versionKey: false }),ن»¥وٹ‘هˆ¶è¯¥ه€¼م€‚ - Leo Gerber
@xperator 结果是方案中没有__V字段: {
"_id": { "$oid": "5aa62e99f36d28237f1a41ad" }, "email": "scott@gmail.com", "sessions": 0 } 与 { "_id":{ "$oid": "5aa62e99f36d28237f1a41ad" }, "email": "scott@gmail.com", "sessions": 0, "__v": 0 }
- dang
1
或者这样 schema.set('versionKey', false); - Stan Wiechers
3
设置为false后的结果是什么?除了它不在文档中之外还有什么? - Someone Special

17

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

@Schema({ versionKey: false })

9

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

请参见以下示例:

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
});

4
在我们的文档中,'__v'字段用于处理“乐观并发”问题。在mongoose中,这个术语基本上意味着:你通过'findOne, findById'获取了一个文档,但是还没有使用mongoose的save()方法。如果在此期间,任何其他代码获取了相同的文档并在第一个文档实例之前使用了.save()方法,那么在这种情况下,如果我们想要(mongoose特定的)抛出版本错误,我们就使用模式中的optimisticConcurrency: true选项。然后mongoose将使用'__v1'来比较这两个文档。如果没有optimisticConcurrency: true选项,'__v'将没有效果,并且mongoose不会将其增加1。注意:在'findOneAndUpdate'等操作中,不会更新'__v'。(只有save()会更新)。

3

2

__v字段被称为版本键。它描述了文档的内部修订版本。这个__v字段用于跟踪文档的修订。默认情况下,它的值为零(__v:0)。

如果您不想使用这个版本键,您可以将versionKey:false作为mongoose.Schema参数使用。

您可以按照以下示例操作...

const mongoose = require('mongoose');

const userSchema = mongoose.Schema(
    {
        name: {
            type: String,
            require: true
        },
        email: {
            type: String,
            unique: true
        },

        password: {
            type: String,
        }
    },
    {
        timestamps: true,
        versionKey: false, // Here You have to add.
    }
)

module.exports = mongoose.model('tbl_user', userSchema)

1
__v通常被称为版本键。 当您在集合中创建一个新文档时,它的版本键(__v)为0。当您第一次更新该文档时,该特定文档的版本键(__v)将变为1。只要您继续更新此文档,这个增量就会继续增加。 例如:
{
    _id: 1,
    name: 'John',
    age: 37,
    __v: 0
  }
After updating:
{
    _id: 1,
    name: 'John',
    age: 40,
    __v: 1
  }

0
我们可以在模式定义中使用 versionKey: false
'use strict';

const mongoose = require('mongoose');

export class Account extends mongoose.Schema {

    constructor(manager) {

        var trans = {
            tran_date: Date,
            particulars: String,
            debit: Number,
            credit: Number,
            balance: Number
        }

        super({
            account_number: Number,
            account_name: String,
            ifsc_code: String,
            password: String,
            currency: String,
            balance: Number,
            beneficiaries: Array,
            transaction: [trans]
        }, {
            versionKey: false // set to false then it wont create in mongodb
        });

        this.pre('remove', function(next) {
            manager
                .getModel(BENEFICIARY_MODEL)
                .remove({
                    _id: {
                        $in: this.beneficiaries
                    }
                })
                .exec();
            next();
        });
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接