#Sorted leaderboard in order using MangoDB

1 messages · Page 1 of 1 (latest)

slender harness
#
async for user in collection.find():
  name = user["_id"]
  total_amount = user["wallet"] + user["bank"]
  leader_board[name] = total_amount
  money.append(name)

print("After: ", leader_board)
money.sort()    

        embed = discord.Embed(color = discord.Color.blue())
        embed.set_author(name = f"{server} Currency Leaderboard")
        index = 1
        for id in money:
                member = self.bot.get_user(id)
                name = member
                if member == ctx.author:
                    rank = index
                embed.add_field(name = "** **", value = f"**{index}.** {name}{leader_board[id]}", inline = False)
                embed.set_footer(text = f"Your leaderboard rank: {rank}")
                if index == limit:
                    break
                else:
                    index += 1
#

I have fixed the issue of key value errors to your suggestion, I was a little tired last night and didn't notice lol. But how would I go about sorting the list now by total_amount

narrow plaza
#

mongoDB can actually sort the values by a document field before it hosts the data to you.

in your "find statement" specify the .sort extension to the field you want to sort by. And then when it serves the data, it will be given in the order based on the sort criteria.

variable = collection.find({}, {"_id": 0, "fieldone": 1, "fieldtwo": 1}).sort("fieldone", -1)

collectionlist = list(variable)

the 1 or 0 allows you to return/ not return the fields in the response.

Hope this helps man.

slender harness
narrow plaza
#

That method usually sorts on 1. But if I’m not mistaken you can do a multi level sort if needed.

slender harness
#

I will definitely have to look into it than, worst case is I can add a 3rd value to the database that would consolidate the 2 into 1

jovial gale
#

btw u should not iterate a leaderboard like that every time it is called... i mean u can but it's not really optimal performance wise

slender harness
#

With Ark's help I figured it out. And ill def look into a way not to go through the leaderboard every time the function is called. Thanks for all the help

        leader_board = {}

        async for user in collection.find():
            name = user["userId"]
            total_amount = user["wallet"] + user["bank"]
            leader_board[name] = total_amount

        sorted_leader_board = sorted(leader_board.items(), key=lambda x: x[1], reverse = True)```
#

When 2 users have the same balance, only one of said user is shown. The leader board application command is in a cog

class LeaderboardCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
    @commands.slash_command(guild_ids = guild_ids, aliases = ["lb"], name = "leaderboard", description = "Check the top 10 richest users")
    async def leaderboard(self, ctx):
        limit = 10
        member = ctx.author
        db = self.bot.mongoConnect["DiscordUserData"]
        collection = db["Economy"]
        server = member.guild.name
        rank = -1

        leader_board = {}
        total = []

        async for user in collection.find():
            name = user["_id"]
            total_amount = user["wallet"] + user["bank"]
            leader_board[total_amount] = name
            print("Before: ", leader_board) 
            total.append(total_amount)

        print("After: ", leader_board)
        total = sorted(total,reverse=True)    

        embed = discord.Embed(color = discord.Color.blue())
        embed.set_author(name = f"{server} Currency Leaderboard")
        index = 1
        for amt in total:
            id_ = leader_board[amt]
            member = self.bot.get_user(id_)
            name = member.mention
            if member == ctx.author:
                rank = index
            embed.add_field(name = "** **", value = f"**{index}.** {name}{amt}", inline = False)
            embed.set_footer(text = f"Your leaderboard rank: {rank}")
            if index == limit:
                break
            else:
                index += 1

        await ctx.respond(embed = embed)```
warm heron
#

first, slash_command() doesn't have aliases

and dict leader_board has same key 2000, so value is overriten. (in async collection.find())
so, i think leader_board[total_amount] = name to leader_board[name] = total_amound.