Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set document's rank in collection depending on score

I have a collection of highscore documents that look like this:

{
  "data": {
    "highscores": [
      {
        "id": "58c02942f9256663764edc3d",
        "userName": "user3",
        "score": 123,
        "rank": null
      },
      {
        "id": "58c02957f9256663764edc3e",
        "userName": "user2",
        "score": 444,
        "rank": null
      },
      {
        "id": "58c02966f9256663764edc3f",
        "userName": "user1",
        "score": 64,
        "rank": null
      },
      {
        and more...
      }
    ]
  }
}

And for now I'm using this line of code to display a sorted highscore list:

this.model.find({}).sort({ score: -1 }).limit(5);

But I want to order it by rank so I can jump to that document by the rank value (and e.g. show the next 9 documents after that). But I don't know how I can iterate through the collection and set the rank depending on user's score value. Can anyone help?

Edit: The higher the score, the higher the rank. So in that example list user2 is first (rank 1), user3 is second (rank 2) and user1 has rank 3.

Edit2: I am using Mongoose. There are some functions that exist in native MongoDB but not in Mongoose.

like image 781
Southgarden116 Avatar asked Oct 18 '22 15:10

Southgarden116


2 Answers

With native driver this can be done as:

var results=db.ranks.find().sort({score:-1}).limit(3).toArray()

for(var i=0;i<results.length;i++)
{    db.ranks.update({id:results[i].id}, {$set: {rank: i+1}}, {multi:true})
}
like image 119
Atish Avatar answered Oct 21 '22 03:10

Atish


Okay I got it to work in mongoose. Thanks to Astro who helped me look in the right direction:

  return this.model.find({}).sort({ score: -1 }).exec((err, docs) => {
  for (var i = 0; i < docs.length; i++) {
    this.model.update({ _id: docs[i].id }, { $set: { rank: i + 1 } }, { multi: true }).exec();
  }
like image 38
Southgarden116 Avatar answered Oct 21 '22 05:10

Southgarden116