mongoose-update-if-current
mongoose-update-if-current copied to clipboard
[ENHANCEMENT] working with updateOne()
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?
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:
- Passing the current version of the document to the query.
- 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!
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.
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.
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.
Any update on this?