How can I properly sort this request to mongodb?

295 Views Asked by At

I want to display user scores ordered by scores:

  const gotHighscore = {
    score: req.body.score,
    name: req.body.name,
    created: new Date() 
  };

I start off with this in my server.js file:

app.get("/getHighscore", (req, res) => {
  gotHighscore
      .find()
      .then(gotHighscore => {
        res.json(gotHighscore);
      });
});

Chrome log:

0: {_id: "5e57afae67db842ff4bf806b", score: "150", name: "Hendel", created: "2020-02-27T12:01:50.173Z"}
1: {_id: "5e57b4fb67db842ff4bf806c", score: "70", name: "123", created: "2020-02-27T12:24:27.351Z"}
2: {_id: "5e57b63667db842ff4bf806d", score: "110", name: "iseemypee", created: "2020-02-27T12:29:42...

The only way of sorting, that does not break everything and seemed easy to implement, looks like this:

app.get("/getHighscore", (req, res) => {
  gotHigscore
      .find({}, {sort : {score: -1}})
      .then(gotHighscore => {
        res.json(gotHighscore);
      });
});

However, it does not order them how you would want it. It seems to me that it orders by the first digit and then second digit, not the value of the integer:

0: {_id: "5e57b4fb67db842ff4bf806c", score: "70", name: "123", created: "2020-02-27T12:24:27.351Z"}
1: {_id: "5e57afae67db842ff4bf806b", score: "150", name: "Hendryk", created: "2020-02-27T12:01:50.173Z"}
2: {_id: "5e57b63667db842ff4bf806d", score: "110", name: "iseemypee", created: "2020-02-27T12:29:42.25...

Any ideas?

Thank you.

2

There are 2 best solutions below

5
Alexis Villicaña On

Save score as number, not as string so sorting will be by number and not by characters.

Make sure score is being saved as number, number values don have quotes {"number" : 5, "string": "string value"}.

db.scores.find() // check our data

{ "score" : 1, "type" : "Hendryck" }
{ "score" : 2, "type" : "iseempyee" }
{ "score" : 3, "type" : "123" }
{ "score" : 4, "type" : "0720" }

db.scores.find().sort({score: -1}) //sort score descending

{ "score" : 4, "type" : "0720" } // number 4 is the highest
{ "score" : 3, "type" : "123" }
{ "score" : 2, "type" : "iseempyee" }
{ "score" : 1, "type" : "Hendryck" } //number 1 is the lowest

db.scores.find().sort({type: -1}) //sort type descending

{ "score" : 2, "type" : "iseempyee" }
{ "score" : 1, "type" : "Hendryck" }
{ "score" : 3, "type" : "123" } // '113' > '0720' with string values
{ "score" : 4, "type" : "0720" } // reason -> '1' > '0' (ascii values)

Try with:

const gotHighscore = {
    score: parseInt(req.body.score, 10), //parseInt(value, base)
    name: req.body.name,
    created: new Date() 
  };

and make sure this object generates:

{ 
  score: 0,  // number
  name: "name", // string
  created: "date"  
}
0
Dudelstrom On

The http body had to be converted from a string to an integer, when saved to the database, in order to be sorted by integer value.

reg.body.score.toInt() did not work (error: not a function), although I've seen it in some places elswhere. Using parseInt solved it for me:

  const mew = {
    score: parseInt(req.body.score),
    name: req.body.name,
    created: new Date() 
  };