Mongoose __v property - hide?
Asked Answered
C

10

77

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

Coronal answered 4/12, 2012 at 9:34 Comment(1)
Possible duplicate of What is the "__v" field in MongooseEliseelisee
C
124

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.

Clintonclintonia answered 4/12, 2012 at 20:28 Comment(3)
is it safe to disable "__v" attribute? will it cause any future issue if I disable it?Gariepy
Is there a way to hide it from the returned docs from queries?Cement
Is it safe? You can read the details here. 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.Intracranial
A
65

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}})
Artemisa answered 16/3, 2014 at 11:43 Comment(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.Lacteous
C
33

Two ways:

  1. {versionKey: false}

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

'-' means exclude the field

Cheapen answered 26/3, 2015 at 2:35 Comment(0)
M
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;
      }
    }
});
Mayramays answered 22/11, 2014 at 10:17 Comment(3)
Alternatively you can call user.toObject({ versionKey: false }), which will hide __v version property.Cory
Do you also need toJSON()?Glooming
@Glooming No, not neededManwell
D
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);
Dividers answered 25/11, 2016 at 7:9 Comment(0)
K
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.

Kozak answered 29/6, 2016 at 6:14 Comment(2)
Why use a library to do this silly simple transformation ? refer toJSON or toObject schema option instead. toObject() worked for me.Manwell
You're right. Other answers have recommended the same thing. @NIKHILCMKozak
D
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

Denticulation answered 12/9, 2020 at 15:30 Comment(0)
S
1

For devs who are using nestJS

https://docs.nestjs.com/techniques/mongodb#model-injection

@Schema({
  versionKey: false, // this will prevent adding the __v when new record is created.
})
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;

  @Prop({ select: false }) // this will hide the __v when you do a select/find query
  __v: number;
}
Sabo answered 23/3 at 7:36 Comment(0)
G
0

set this after connected to DB (server.js)

mongoose.modelNames().forEach(function (modelName) {
    mongoose.model(modelName).schema.set("versionKey", false);
});
Graniteware answered 23/11, 2023 at 8:8 Comment(1)
doesnt work. still shows up.Soluble
D
-23

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)

Dunlavy answered 29/9, 2017 at 17:57 Comment(2)
This is terrible advice.Regina
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.Downright

© 2022 - 2024 — McMap. All rights reserved.