var dailySchema = new Schema({
_id: String,
date: String,
lastAccessTime: Date,
hits: Number,
totalElapsedTime: Number,
hourly: {},
}, {collection: 'daily'});
The daily collection contains 1 doc for each day. The "hourly" field stores hour/minute aggregate data over the course of the day which gets upserted as data comes into the service. The sub doc looks like this:
hourly: {
"00": {
"00": {
"hits": 10,
"totalElapsedTime": 35235
},
......
"59": {
"hits": 8,
"totalElapsedTime": 435
}
},
......
"23": {
"00": : {
"hits": 221,
"totalElapsedTime": 113535
}
}
}
If the collection doesn't contain a document for the current day, it should first initialize the hourly sub-document fields to zeros for each hour and minute (0..23 x 0..59) then update the hour/minute aggregate based on the hour/minute contained on the incoming data (i.e. $incr {hourly.01.45.hits: 1}). The logic looks like this:
if (daily.apps.find({date: "20161021"}) == null) {
initialize hourly sub doc to zeros
increment specific hour/minute hits and totalElapsedTime in sub doc
} else {
increment specific hour/minute hits and totalElapsedTime in sub doc
}
Problem: How can I avoid a race condition when doing the initialization + update (i.e. the service receives 2 incoming requests in parallel at the start of the day)? I can't just do an upsert since the hourly data in the 2nd update will overwrite the first. Is there a way to lock the collection when I check to see if a doc exists to do the initialization + update?
Thanks,
Fred