Search code examples
node.jsmongodbmongoosediscord.js

How to list all documents in a mongodb collection in ascending order mongoose


I am trying to list the documents in my level collection by the lowest level to the highest, but that is not working. My code is

const lvl = await Level.find({}).sort({level: 1});

for the filter, and I list it over here:

    lvl.forEach(entry => {
        embed.addFields({ name: `Level ${entry.level}`, value: `Xp Required: ${entry.xp}`});
    })

The code for the level schema is:

const mongoose = require("mongoose");

const LevelSchema = new mongoose.Schema({
    level: mongoose.Schema.Types.String,
    xp: mongoose.Schema.Types.String,
});

module.exports = mongoose.model("levels", LevelSchema);

This code is working completely fine, the only issue is that it comes in the order that the documents are in the collection, and not by the lowest level to the highest like I want it to. I did what the documentation told me to do in the .sort({level: 1}) part, but that didn't change anything either.


Solution

  • You can use mapping your array, lets re-construct your code for a bit:

    this part of your code is okay:

    await Level.find({}).sort({level: 1});
    

    But you might need to do it as Array Object. So to work this out. Change the code line to

    Level.find({}).sort([['level', 'ascending']]); //remove the await
    //ascending = 1, descending = -1
    

    Adding the .exec() will do the trick:

    Level.find({})
    .sort([['level', 'ascending']])
    .exec((err, res) => {
       if(res) {
         //There's an existing data
         //Let's use your method on embed.
         let embed = new MessageEmbed()
         .setDescription("OPTIONAL")
         .setColor("YOUR_COLOR")
         .setTitle("OPTIONAL")
         .setTimestamp() //OPTIONAL
         const result = res.map((value, index) => {
            return(embed.addFields({name: `Level: ${res[index].level}`, value: `Xp Required: ${res[index].exp}`}))
         }).join("\n");
         result
    
         message.channel.send({embeds: [embed]})
       } else {
         //No data message
       }
    })
    

    Since the sorting detects only the first number, you need to add .collation({locale: "en_US", numericOrdering: true}).

    from this:

    Level.find({}).sort([['level', 'ascending']])
    

    Turn it to this:

    Level.find({}).sort([['level', 'ascending']]).collation({locale: "en_US", numericOrdering: true})