Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose versioning: when is it safe to disable it?

Tags:

From the docs:

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:

[...]

Document versioning can also be disabled by setting the versionKey to false. DO NOT disable versioning unless you know what you are doing.

But I'm curious, in which cases it should be safe to disable this feature?

like image 548
franzlorenzon Avatar asked Jul 23 '13 12:07

franzlorenzon


People also ask

What is Version Key in Mongoose?

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.

What does _V mean in MongoDB?

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.

How does Mongoose know which collection?

Mongoose uses the model name, as passed when it was created: mongoose. model("User", UserSchema) , converted to lower case and with an 's' appended. For the model User it uses the collection users by default. You can change this by explicitly specifying the collection name in the schema.

Why do we use Mongoose?

Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node. js. It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB. MongoDB is a schema-less NoSQL document database.


1 Answers

The version key purpose is optimistic locking.

When enabled, the version value is atomically incremented whenever a document is updated.

This allow your application code to test if changes have been made between a fetch (bringing in version key 42 for example) and a consequent update (ensuring version value still is 42). If version key has a different value (eg. 43 because an update has been made to the document), your application code can handle the concurrent modification.

The very same concept is often used in relational databases instead of pessimistic locking that can bring horrible performance. All decent ORMs provide such a feature. For example it's nicely described in ObjectDB documentation. It's an object database implemented in Java but the same concept applies.

The blog post linked in Behlül's comment demonstrate the optimistic locking usefulness with a concrete example, but only for arrays changes, see below.

On the opposite, here is a simple case where its useless: a user profile that can be edited by its owner ownly. Here you can get rid of optimistic locking and assume that the last edit always wins.

So, only you know if your application need optimistic locking or not. Use case by use case.

The Mongoose situation is somewhat special.

Optimistic locking is enabled only for arrays because the internal storage format uses positional index. This is the issue described by the blog post linked in the question's comment. I found the explanation given in the mongoose-orm mailing list pretty clear: if you need optimistic locking for other fields, you need to handle it yourself.

Here is a gist showing how to implement a retry strategy for an add operation. Again, how you want to handle it depends on your use cases but it should be enough to get you started.

I hope this clears things up.

Cheers

like image 58
eskatos Avatar answered Oct 15 '22 08:10

eskatos