23

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?

Behlül
  • 3,412
  • 2
  • 29
  • 46
franzlorenzon
  • 5,845
  • 6
  • 36
  • 58
  • 1
    This blog post talks about the case where you access elements in subdocument array positionally. But mongoose in fact uses ids instead of positions. So I am not sure either: http://aaronheckmann.tumblr.com/post/48943525537/mongoose-v3-part-1-versioning – Behlül Sep 23 '13 at 09:00

1 Answers1

57

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

ZachB
  • 13,051
  • 4
  • 61
  • 89
eskatos
  • 4,174
  • 2
  • 40
  • 42
  • 1
    Do we need versioning if we are using `$in` operator to reach to subdocuments. It doesn't seem different than accessing to the parent document to me. – Behlül Sep 23 '13 at 09:55
  • Once again, it depends on the use case. When using the $in operator, you tighten the concurrent modification window but remember that it's still open. – eskatos Sep 23 '13 at 10:01
  • 2
    @esKotos I think Your new updated answer looks ambiguous because versioning not work when we only update any non array field. – Sandeep Sharma Jun 21 '16 at 18:43
  • @esKotos Apart from that What if I'm not modifying an array field and want to achieve this feature? – Sandeep Sharma Jun 21 '16 at 18:48
  • 2
    @SandeepSharma you need to call document.increment(), before any save(). This will give the signal to increment version, in case of save success (validation ok and no version conflict) – Cédric NICOLAS Sep 09 '16 at 18:39