Simon Lomax
Simon Lomax

Reputation: 8982

What is the "__v" field in Mongoose

I'm using Mongoose version 3 with MongoDB version 2.2. I've noticed a __v field has started appearing in my MongoDB documents. Is it something to do with versioning? How is it used?

Upvotes: 448

Views: 267769

Answers (10)

shea
shea

Reputation: 296

The following is just a rejected edit to ratyacatnug's great answer:

The __v field in a document serves Mongoose's implementation of concurrency control (including optimistic concurrency).

For example, say you grab a document with findOne/findById but have not used save() yet. During this interval, if any other code fetches the same document and uses the save() method before the first document instance saves, it causes a versioning conflict between the two.

Mongoose has built-in version control to address these situations. When the first document instance calls save(), it increments its copy of __v. When the second document instance calls save(), Mongoose detects the mismatch via their different __v values.

Mongoose will use __v to compare the two document instances and detect version conflicts.

If we want to throw an error to alert about the version conflict, we use optimisticConcurrency: true option in the schema [options] object. When optimisticConcurrency: false, __v is not used for modifications to the entire document (although it is still used for sub-arrays, see the docs for a clarifying example) - each save() will overwrite any previous contents.

As seen in Tony's answer, the property name of __v can also be customized using versionKey: <customName> in a schema's [options] object. As seen in ken's answer, Mongoose's versioning can be disabled entirely with versionKey: 'false' - that way, __v won't be incremented, referenced, or defined at all.

Note: findOneAndUpdate operations do not update '__v' (only save()).

Upvotes: 0

kenberkeley
kenberkeley

Reputation: 9856

Well, I can't see Tony's solution...so I have to handle it myself...


If you don't need version_key, you can just:

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

Setting the versionKey to false means the document is no longer versioned.

This is problematic if the document contains an array of subdocuments. One of the subdocuments could be deleted, reducing the size of the array. Later on, another operation could access the subdocument in the array at it's original position.

Since the array is now smaller, it may accidentally access the wrong subdocument in the array.

The versionKey solves this by associating the document with the a versionKey, used by mongoose internally to make sure it accesses the right collection version.

More information can be found here.

Upvotes: 112

Bilal Gillani
Bilal Gillani

Reputation: 39

__v is commonly known as version key. When you create a new document in a collection, its version key(__v) is 0. The version key(__v) of that particular document changes to 1 when you update it for the first time. This increment continues as soon as you continue updating this document. For example:

{
    _id: 1,
    name: 'John',
    age: 37,
    __v: 0
  }
After updating:
{
    _id: 1,
    name: 'John',
    age: 40,
    __v: 1
  }

Upvotes: 3

ratyacatnug
ratyacatnug

Reputation: 161

the '__v' field in our 'document' serves 'optimisticConcurrency' concerns.

This term basically means in mongoose : let, you grabed a document by 'findOne, findById' but not used save() method of mongoose yet. and what if at this interval, any other code grabed same document and used .save() method before the first document instance. at this use case, if we want to (mongoose specific) throw a version error kinda thing, we use optimisticConcurrency: true option in schema.

and then mongoose will use '__v1' to compare these two document.

without optimisticConcurrency: true option. '__v' has no has no effect. and mongoose will not increase it by 1.

Note : in 'findOneAndUpdate' kinda operations, will not update '__v'. (only save() updates)

Upvotes: 6

Nandeep Barochiya
Nandeep Barochiya

Reputation: 426

The __v field is called the version key. It describes the internal revision of a document. This __v field is used to track the revisions of a document. By default, its value is zero (__v:0).

If you don't want to use this version key you can use the versionKey: false as mongoose.Schema parameter.

You can follow this example...

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)

Upvotes: 2

Lysak
Lysak

Reputation: 393

For remove in NestJS need to add option to Schema() decorator

@Schema({ versionKey: false })

Upvotes: 21

Nguyen Phu
Nguyen Phu

Reputation: 106

It is possible to disable the version key if you don't need it.

See this example:

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

Upvotes: 9

Muhammed shakir CK
Muhammed shakir CK

Reputation: 171

It is the version key.It gets updated whenever a new update is made. I personally don't like to disable it .

Read this solution if you want to know more [1]: Mongoose versioning: when is it safe to disable it?

Upvotes: 4

KARTHIKEYAN.A
KARTHIKEYAN.A

Reputation: 20158

We can use versionKey: false in Schema definition

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

}

Upvotes: 0

Tony The Lion
Tony The Lion

Reputation: 63310

From here:

The versionKey is a property set on each document when first created by Mongoose. This keys value contains the internal revision of the document. The name of this document property is configurable. The default is __v.

If this conflicts with your application you can configure as such:

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

Upvotes: 425

Related Questions