1

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?

5
  • Is your problem arise only when a new year begins? Commented Aug 6, 2019 at 12:51
  • you want only solution for new year right? Commented Aug 6, 2019 at 12:52
  • @AnushkaAhir Yes exactly. Commented Aug 6, 2019 at 13:00
  • In again update operation what you want to perform? you want to increment the value or else? Commented Aug 6, 2019 at 13:05
  • I always want to increment the value inside the object with the current year. Now if there is no object for the current year I need to create it. Currently I do check if the first update did modify a document and if not I create an element for this year, but this seems a bit hacky. Commented Aug 6, 2019 at 13:08

1 Answer 1

1
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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.