Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

__v field causing mongo errors #1933

Closed
dillonkrug opened this Issue · 7 comments

7 participants

@dillonkrug

I'm getting this error when saving a document:

{
    name: "MongoError",
    err: "Field name duplication not allowed with modifiers",
    code: 10150,
    n: 0,
    connectionId: 1,
    ok: 1
}

the mongo diaglog shows that the query in question did this:

update flags: 0 q: {
    __v: 11,
    _id: ObjectId('527a7c1ca2d740dd0f000004')
}
o: {
    $set: {
        __v: 11,
        aaaa.bbbbb: [{
            _id: ObjectId('52a115780594725664000001'),
            type: "xxxxx",
            name: "xxxxxxxxxxxxxxxx"
        }],
        cccc.ddddd: [{
            _id: ObjectId('527136c893312c254a0000b7'),
            type: "xxxxx",
            name: "xxxxxxx"
        }, {
            _id: ObjectId('52a115780594725664000001'),
            type: "xxxxx",
            name: "xxxxxxxxxxxxxxx"
        }],
        tttttt: new Date(1393008423258)
    },
    $inc: {
        __v: 1
    }
}

Not that it's both {$set: {__v: 11}} and {$inc: {__v:1}}, which mongo does not like.

@aheckmann
Owner

interesting. please post the code you used to reproduce so we can track it down and fix it.

@aheckmann aheckmann added the bug? label
@dillonkrug

While I was trying to write a test case I realized the source of the error. We send the document as JSON to the client, where it is modified, then the client sends it back and we merge any changed data with a clean copy from the database, then save it.

the $set : __v part of the invalid query comes from the merge, and the $inc : __v comes from mongoose internally, because an array field was modified.

This problem can easily be solved by our code simply ignoring the __v field during the merge.

That said, if setting the __v field causes difficult to trace errors ("Field name duplication not allowed with modifiers" is all the information available without going to the mongo diaglog) perhaps a preemptive warning of some sort would be appropriate.

The simplest way to reproduce this error:

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/test');

var Test = mongoose.model('Test', new mongoose.Schema({
    id: String,
    field: [{}],
}));

var doc = new Test();
doc.save(function(err) {
    Test.findOne(function(err, doc) {
        doc.__v = 123;
        doc.field.push({_id: 'xxxxx', type: 'nnn'});
        doc.save(function(err) {
            console.log(err);
        })
    })
})
@onyxrev

I also have observed this bug when modifying an array client-side and then sending back the new array in an update.

A workaround is to not select the __v attribute in the Schema:

  __v: {type: Number, select: false}

What are the bad things™ that will happen as a result of doing this? Is it functionally the same as turning off versioning altogether?

@skaapgif

@onyxrev https://github.com/LearnBoost/mongoose/blob/3.8.x/lib/model.js#L486 unselecting the __v field disables the versioning functionality. Which then wouldn't prevent race conditions on seperate find and save calls.

As the docs clearly state that "__v" or versionKey is the internal document version key, I think the expected behaviour is that this private field would not be changed by a set() call but instead is only ever changed in mongoose' internals.

@aheckmann would you be happy with ignoring (with warning perhaps) any set with versionKey == key? What's the best place for doing this in Document.$__set

@marco48

Hi Guys,
Any news on this, i have the same issue... Is there any way to get ride of this without unselecting the __v field..?

@diaswrd

@marco48 I'm not sure if it's the best approach, but I'm just removing the __v attribute from my json data before every update. Seems to work fine for me, because in the updated result the __v will be returned incremented as it should.

@marco48
@vkarpov15 vkarpov15 added this to the 3.8.15 milestone
@vkarpov15 vkarpov15 closed this in c2c4d98
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.