Home > front end >  Update score in MongoDB only if it a higher score
Update score in MongoDB only if it a higher score

Time:10-01

I've made a game and implemented a leaderboard with a player name and score.

But currently if you get a score of say 5 and play again and get a score of say 3 then the score is updated to 3, but I want the highest score you got to remain.

This is my current code, it finds the user by id and sets the id, name, score.

const users = await mongodb.getDb()
  .db('footballers')
  .collection('users')
  .updateOne(
    { _id }, 
    { $set: {_id, name, score } },
    { upsert: true }
  );

I tried to add $max field as apparently this will only update the field if it higher than the previous but the database never appears to update. I even tried putting $max to 0 and got a score of 1 and nothing happened.

Any ideas? Thanks

const users = await mongodb.getDb()
  .db('footballers')
  .collection('users')
  .updateOne(
    { _id }, 
    { $set: {_id, name, score } },
    { $max: { score: 0 } },
    { upsert: true }
  );

CodePudding user response:

If you're building a leaderboard, you don't need to update the fields _id and name fields every time you're trying to update the score. For updating the score of a user only when his/her current score is higher than his/her past score, you can pass a less than filter to the updateOne query.

const users = await mongodb.getDb()
  .db('footballers')
  .collection('users')
  .updateOne(
    { _id, score: { $lt: _score } }, 
    { $set: { score } },
    { upsert: true }
  );

Assuming _score is the current score you're trying to update in the database. This will only fetch the document from the database where _id matches and saved score is less than _score.

Edit: Above query would give the desired behaviour if you already have documents in users collection. In this case, upsert will cause duplicate values for _id. To achieve what you desire, you can use this:

const users = await mongodb.getDb()
  .db('footballers')
  .collection('users')
  .updateOne(
    { _id }, 
    { $set: { _id, name }, $max: { score: _score } },
    { upsert: true }
  );
  • Related