76

Mongoose adds a '__v' property into Schema's for versioning - is it possible to disable this globally or globally hide it from all queries?

leepowell
  • 3,838
  • 8
  • 27
  • 35
  • Possible duplicate of [What is the "\_\_v" field in Mongoose](https://stackoverflow.com/questions/12495891/what-is-the-v-field-in-mongoose) – KARTHIKEYAN.A Oct 16 '19 at 07:46

8 Answers8

119

You can disable the "__v" attribute in your Schema definitions by setting the versionKey option to false. For example:

var widgetSchema = new Schema({ ... attributes ... }, { versionKey: false });

I don't think you can globally disable them, but can only do it per Schema. You can read more about Schema's options here. You might also find the Schema set method helpful.

theabraham
  • 15,840
  • 9
  • 42
  • 41
  • 20
    is it safe to disable "__v" attribute? will it cause any future issue if I disable it? – Nam Nguyen Sep 10 '13 at 23:09
  • 4
    Is there a way to hide it from the returned docs from queries? – Diosney Dec 14 '13 at 20:40
  • 6
    Is it safe? You can read the details [here](http://aaronheckmann.tumblr.com/post/48943525537/mongoose-v3-part-1-versioning). TL:DR; Mongoose uses the version key to help avoid errors encountered by positional notation e.g. `$set: { 'comments.3.body': updatedText }`. If you read a document and use that update statement but someone modifies the `comments` array in the meantime you could update the wrong comment. With a version key you will get an exception in that case. – Pace Mar 27 '18 at 13:41
61

To disable '__v' property, which is not recommended, use the versionKey schema option:

var Schema = new Schema({...}, { versionKey: false });

To hide it from all queries, which sometimes can be not what you want too, use the select schema type option:

var Schema = new Schema({ __v: { type: Number, select: false}})
Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
Alexander Gonchiy
  • 916
  • 11
  • 17
  • 1
    So how can I delete _id and __v before returning them to user? Is there any kind of mapping I can do? Mapping from schema to model would remove these two attributes and mapping from model to schema would let's say remove some fields user should not be able to edit but still see them. – Dread Boy Sep 23 '14 at 20:49
33

Two ways:

  1. {versionKey: false}

  2. when you query, like model.findById(id).select('-__v')

'-' means exclude the field

sqluser
  • 5,502
  • 7
  • 36
  • 50
EarthShaker
  • 331
  • 3
  • 4
24

define a toObject.transform function, and make sure you always call toObject when getting documents from mongoose.

var SomeSchema = new Schema({
    <some schema spec>
  } , {
    toObject: {
      transform: function (doc, ret, game) {
        delete ret.__v;
      }
    }
});
Amit Portnoy
  • 5,957
  • 2
  • 29
  • 30
8

Try this it will remove _v from every query response.

// transform for sending as json
function omitPrivate(doc, obj) {
    delete obj.__v;
    return obj;
}

// schema options
var options = {
    toJSON: {
        transform: omitPrivate
    }
};
// schema
var Schema = new Schema({...}, options);
Simran
  • 2,364
  • 1
  • 12
  • 19
6

You may not want to disable __v, other answers provide few links to answer why you shouldn't disable it.

I've used this library to hide the __v and _id

https://www.npmjs.com/package/mongoose-hidden

let mongooseHidden = require("mongoose-hidden")();

// This will add `id` in toJSON
yourSchema.set("toJSON", {
        virtuals: true,
    });

// This will remove `_id` and `__v` 
yourSchema.plugin(mongooseHidden);

Now __v will exist, but it won't be returned with doc.toJSON().

Hope it helps.

Ashwani Agarwal
  • 1,279
  • 9
  • 30
5

You can use a Query Middleware to exclude any field from the output. In your case you can use this:

// '/^find/' is a regex that matches queries that start with find
// like find, findOne, findOneAndDelete, findOneAndRemove, findOneAndUpdate
schema.pre(/^find/, function(next) {
    // this keyword refers to the current query
    // select method excludes or includes fields using + and -
    this.select("-__v");
    next();
});

For more information in docs lookup: Middlewares select method

Miad Abdi
  • 831
  • 10
  • 17
-22

Yes, it is simple, just edit the "schema.js" file that is inside

"node_modules\mongoose\lib"

Search for "options = utils.options ({ ... versionKey: '__v'..." and change value "__v" to false.

This will change all post requests. (versionKey: '__v' => versionKey: false)

Dmitry
  • 6,716
  • 14
  • 37
  • 39
  • 17
    This is terrible advice. – arg20 Nov 29 '18 at 16:08
  • 1
    You should not change code inside `node_modules`. The content of this folder changes often with npm install and it should be added to `.gitignore`. Whatever you write there will be lost. – Andréa Maugars Jan 21 '20 at 09:32