Reputation: 311
I want to store/update statistics for each year. I have the following model
{
entityid: ObjectId,
stats: [
{ year: 2018, value: 25 }
]
}
(This model is a bit simplified, in reality the year has also an array with months -> days -> hours. But the problem stays the same for the simplified model)
For updating I can simply use $inc like
db.statistics.updateOne(
{entityid, 'stats.year': 2018},
{$inc: { 'stats.$.year': 1}}
)
But now a problem arises when a new year begins because there will be no { year: 2019, value: 0 }
inside the stats array. Upsert can not really be used because of the positional operator $.
The current solution is to check the result of the update query above if we actually modified a document. If no changes were applied we execute a push to insert the array element for the new year and execute the update again.
The solution feels like a hack and produces some problem with race conditions where multiple objects are pushed for the same year, although this can be fixed easily.
Can the update/push operation be performed in one go? Or is there a better database model to store this information?
Upvotes: 1
Views: 147
Reputation: 1284
You can either follow your hack or make database like this and use upsert on the year key while using $inc on value
{
entityid: ObjectId,
year: 2018,
value: 25
}
and use $group on entityid while fetching data if you want to group data.
Upvotes: 1