Reputation: 55856
I am new to Mongo. I wanted to atomically upsert a document based on multiple criteria. The document looks like the following:
{_id:..., hourOfTime:..., total:..., max:..., min:..., last:...}
This is basically hourly aggregation for number of clicks for an item identified by _id
. The clicks for each item is is flushed from the application to MongoDB every five seconds. So, the document need to be updated every five seconds.
Here is the case. Lets say at t=t0
, we have {_id:"nike", total:123, max:10, min:3, last:9}
then at t=t1
, I get message {_id:"nike", count: 12}
. Now, for _id="nike"
, I need to do the following,
total
by 12
max < 12
, update max=12
min > 12
, update min=12
last=12
I want all this operation to be atomic. I unable to convert this in one single query. Any help/hint is appreciated.
Upvotes: 0
Views: 1109
Reputation: 2699
This cannot be done with a single query. Here is how I would do it:
locked
. Run a findAndModify
to grab the document if the locked
field is false, and set the locked field to the Date()
that it is locked at. This will stop other application instances from modifying the document, providing they also check for the locked
field.locked
to false.
As long as anything modifying the document runs a findAndModify
on the locked
field, this entire modification should be atomic.Make sure to have a threshold at which a lock times out, so that documents do not become locked indefinitely if a machine blows up. This means that when updating the document the second time (and releasing the lock), the application should make sure that the date in the document is what it expects, to make sure it still has the lock.
Upvotes: 1