Mongoose: Question: can $inc be used with Document#save()?

Created on 24 Mar 2017  路  2Comments  路  Source: Automattic/mongoose

Trying to accomplish emitting events for create / update / delete from schemas. Using the document pre save hooks works great for the most part, I know I can use MongooseArray to cover operations like $push and $pop even with Document#save(), which is perfect for those.

However, there are a few places where we need to worry about using $inc for numbers. I know an extension of the number class existed at one point but was deprecated.

I think I have a few potential options:

  1. Issue an $inc operation with Document#save(), if that's still possible
  2. Increment __v whenever we are doing an operation which should actually be an $inc, then just do doc.number += amount, allow VersionError to throw

    1. Could potentially be bad UX, or we could potentially add some sort of automatic retry on VersionError (that strikes me as possibly dangerous, though, if more than just $inc is occurring in the update)

  3. Issue a findByIdAndUpdate to use $inc

    1. Problems here are with emitting update events. With the document middleware, we had access to utilizing modifiedPaths(). With query middleware, I don't believe anything like that is available? In order to make this work with a list of changes, we'd have to store the original version of the document, then do some manual deep equality / diffing of the previous / current versions of the document afterward to figure out what exactly changed. We would almost need the new option to be both true _and_ false, haha.

Any suggestions? If github issues aren't the proper place to ask a question for this repo, I apologize -- feel free to close and I'll just move my question over to stackoverflow or something.

Most helpful comment

There's no way to use $inc with save() right now. If you need $inc, I'd recommend doing the findByIdAndUpdate route. You theoretically shouldn't need to do diffing or access modifiedPaths(), because with findByIdAndUpdate() you're constructing the update manually, no?

All 2 comments

There's no way to use $inc with save() right now. If you need $inc, I'd recommend doing the findByIdAndUpdate route. You theoretically shouldn't need to do diffing or access modifiedPaths(), because with findByIdAndUpdate() you're constructing the update manually, no?

Yeah, we are building the update ourselves internally. We can always feed the changes back into the system manually if we have to, since we know what is going to be updated. I was hoping for something more automatic -- maybe a look into the query provided to pre-findByIdAndUpdate events to determine which props may have changed? Assuming I have or can get access to the query from the pre-hook inside the post-hook, anyways.

We had also looked at utilizing the oplog instead of the mongoose hooks, but that was actually quite painful for our multi-tenant database (we needed the context of the tenant for each change). The mongoose events worked out perfectly for that, other than $inc. We were also looking trying to grab just the diff between objects because it actually gets utilized for a couple different places (replication, socket emits, model level changelogs, etc), so we were aiming for the most trim set of data possible.

But that's okay -- if it doesn't exist, then it doesn't exist, and we'll figure out a way to work around it. Thanks for the response! I appreciate it.

Was this page helpful?
0 / 5 - 0 ratings