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 }
);