mongoose-update-if-current icon indicating copy to clipboard operation
mongoose-update-if-current copied to clipboard

[ENHANCEMENT] working with updateOne()

Open zsimoes opened this issue 5 years ago • 5 comments

Is there a viable way to adopt a similar strategy with Model.updateOne()?

Pondering on how the pre-save hook works, I understand any document that is retrieved from the database (that can subsequently be save()d) is guaranteed to have a version key which can be used in the $where clause of the current query. An updateOne() operation might not have a versionKey suitable for this purpose.

I believe a pre('updateOne') hook could have the same functionality as pre('save') if the query passed has a key that matches the schema versionKey. Is this too naïve, or am I missing some obvious difficulty?

Otherwise, is there an interest in adding this functionality to this package, or does it fall out of scope?

zsimoes avatar Dec 12 '19 15:12 zsimoes

Good question! I've thought it over, and I think I can definitely add this once a few design decisions have been made. There would be two elements to getting this working:

  1. Passing the current version of the document to the query.
  2. Incrementing the document's version key if the update succeeds.

Grabbing the version key from the filter parameter in the pre-update hook is straightforward, as is adding a $set or $inc for the version key. An issue could arise where the version key is absent from the filter or the version key is a complex query, e.g. version: { $gte: 4, $lte: 10 }, rather than a number.

To avoid any unexpected behaviour and stick to the principle of least astonishment, the best way to implement this might be to pass a flag to the updateOne call to explicitly switch on OCC functionality. A call might look something like this:

await Person.updateOne({ name: 'Jean-Luc Picard' }, { ship: 'USS Enterprise' }, { occ: <version> });

Having the version key for OCC explicitly passed in the options parameter would help the library keep to the principle of least astonishment and allow the user to update an existing codebase relatively simply.

Let me know what you think of the above!

eoin-obrien avatar Dec 15 '19 23:12 eoin-obrien

Thanks for the feedback :)

I agree, an explicit flag in the updateOne options sounds like the best strategy to prevent unwanted/unexpected behaviour, and allow incremental codebase updates. It also takes care of the complex version key query problem.

Another point: Is this also applicable to timestamps? E.g. depending on the plugin used on a given schema (version key or timestamp) the value of the occ flag could be assumed to be a versionKey or a timestamp.

zsimoes avatar Dec 16 '19 16:12 zsimoes

Thanks! Yes, I'd think that the timestamp plugin would work in much the same way as the version key plugin; the only difference would be that Mongoose automatically updates the updatedAt timestamp field, so we wouldn't need to include a $set for that at all.

eoin-obrien avatar Dec 16 '19 21:12 eoin-obrien

Great! I don't have time to submit a PR right now, but if you want help with this feature around mid-January I'll gladly help.

zsimoes avatar Dec 17 '19 21:12 zsimoes

Any update on this?

GitProdEnv avatar Sep 10 '20 08:09 GitProdEnv