How to find a player's rank in an entire OrderedDataStore?

I have an OrderedDataStore that keeps track of every player’s wins value. I want to find out a player’s rank regardless of what “page” they are on. How could I do this? Would I have to find some tacky method to make the Page Size the number of entries in said OrderedDataStore? How would I do that?

2 Likes

Just use GetAsync. An OrderedDataStore is just like a regular data store except it has the ability to sort the keys.

1 Like

I’ve tried that. Rather then returning the player’s rank (the index that the player is at in the OrderedDataStore), it returns the data.value for that entry

1 Like

For instance, if the player is in 1st place in the OrderedDataStore with, say, 12 wins, it would return 12. No matter what page the data is on, I want it to return the rank. The player could be in rank 500,000 and have 2 wins and I would still want it to return 500,000.

2 Likes

Oh that’s what you meant. You could loop through the pages with a function until the script is able to find the data for the given player on that page

2 Likes

What would that code look like though? Is there a way to definitively get the number of pages for a for loop?

2 Likes

Have you tried requesting a page size with the pagesize as math.huge(). Probably a terrible idea but I’m just throwing the idea out there. Sorta surprised there isn’t a function or sorts for this since I feel like my method is super hacky and probably won’t work at full scale.

1 Like

Basically, when you’re getting the OrderedDataStore, use the GetCurrentPage function to get all the data on that page with a for loop. If the player’s data wasn’t found then use the AdvanceToNextPageAsync function and do it over again

1 Like

Yes, it gives an error. Also, thank you @HugeCoolboy2007!

1 Like

Sorry, I prematurely marked your post as the solution. This code is giving me an error:

local rankList = leaderboardDatastore:GetSortedAsync(false, 10)
repeat
	local page = rankList:GetCurrentPage()
	for plrRank, data in pairs(page) do
		print(data.key, player.UserId, rank)
		if tonumber(data.key) == tonumber(player.UserId) then
			rank = plrRank
		end
	end
	if rank ~= nil then
		rankList:AdvanceToNextPageAsync()
	end
	wait()
until rank ~= nil

“No pages to advance to”

By the way, “leaderboardDatastore” is just the OrderedDataStore.

AdvanceToNextPageAsync can fail if there are no more pages to advance to. To combat this, you have to wrap it in a pcall

local rankList = leaderboardDatastore:GetSortedAsync(false, 10)

local function GetPlayerRank(player) : number | nil
	local page = rankList:GetCurrentPage()

	for plrRank, data in ipairs(page) do -- you should use ipairs for numerical tables (arrays) which GetCurrentPage returns
		print(data.key, player.UserId, rank)
		if tonumber(data.key) == tonumber(player.UserId) then
			return plrRank -- returns the player's rank
		end
	end

    local advanced, err = pcall(function()
		rankList:AdvanceToNextPageAsync()
    end)

    if not advanced then
        return warn("Unable to advance to next page:", err) -- returns nil
    end

    return GetPlayerRank(player) -- does the function again
end
6 Likes

Thank you! It works like a charm now.

2 Likes

cc @NickIsANuke

Note that you could also use .IsFinished before :AdvanceToNextPageAsync to prevent unnecessary calls. You should still use pcall as :AdvanceToNextPageAsync is a network call and can fail, but not for detecting if you’re on the final page.

Reference:

3 Likes

Sorry to revive this topic. But I was working exact same situation where I was trying to retrieve what would be the “rank” of an entry from an ordered datastore. While I had no issues with sifting through all the pages. I have to wonder the consequences and request budget usage when the rank of the player entry is massively low/high. It would be extremely beneficial performance and budget wise if there was a way to grab an index value while accessing an entry directly say by using a regular GetAsync() call with the OrderedDataStore. Does anyone know how to achieve that or are we stuck sifting through potentially 100s of thousands of entries until we find the index among the pages?