GSmGpE6CwX2y9JjB25B8
We use cookies on this site to enhance your user experience

Ordered Data Store

Ordered Data Store

Aug 29 2019, 9:36 AM PST 5 min

Regular Articles/Data store do not sort their content in any way. For many applications this is not a concern, but there are times when it is nice to get data in an ordered fashion (such as a leaderboard). While one could write their own sort for data pulled from a Data Store, this can be expensive and inefficient. Hence the ordered data store. An Ordered Data Store is a Data Store that only contains integers that can return its content in a sorted order. Additionally, one can pull multiple records at once from a Ordered Data Store (as opposed to regular Data Stores where you can only request one key/value pair at a time).

How to Use

Ordered Data stores can be accessed in places with the same criteria as regular Data Stores.

Ordered data stores can be accessed only through a Server Script. Local Scripts do not have access to data stores.

Before modifying or reading the DataStore, you must initialize a variable that points to it:

local ods = game:GetService("DataStoreService"):GetOrderedDataStore(name, scope or "global")

Key API

Ordered Data Stores have the same functions as regular Data Stores (GetAsync, UpdateAsync, IncrementAsync, SetAsync, OnUpdate).

Methods

GetSortedAsync(isAscending, pageSize, minValue = nil, maxValue = nil)

Returns a Pages object. A Pages object is essentially a table of pages, each of which is a sorted list of the key/value pairs in the Ordered Data Store. The length of each page is determined by pageSize, and the order is determined by isAscending. minValue and maxValue are optional parameters which will filter the result.

pages:AdvanceToNextPageAsync()

Iterates to the next page in pages object.

pages:GetCurrentPage()

Returns current page as list of key/value pairs.

Properties

pages.IsFinished

Value is true if current page is last page in pages.

Example Code

lua
ods = game:GetService("DataStoreService"):GetOrderedDataStore("HighScores") -- Assigning 'ods' variable to the ordered data store
 
-- Populate ordred data store
ods:SetAsync("Frodo", 10)
ods:SetAsync("Sam", 12)
ods:SetAsync("Pippin", 8)
ods:SetAsync("Merry",9)
ods:SetAsync("Bilbo", 10)
 
local pages = ods:GetSortedAsync(false, 3) 							-- Get all data from ordered data store as Pages object
local currentPageNumber = 0
while true do	
	print("Page: " .. currentPageNumber)
	local data = pages:GetCurrentPage()              				-- Assigning 'data' variable to the current page of Pages object
	for _, pair in ipairs(data) do 			             				-- Iterates through all key value pairs in 
		print(pair.key .. ": " .. pair.value .. " points")	
	end
	if pages.IsFinished then										-- Checks if last page has been reached
		break
	end
	pages:AdvanceToNextPageAsync()									-- Iterates to next page
	currentPageNumber = currentPageNumber + 1
end

Sample Place

Lets build a simple leaderboard where score is accumulated by clicking on a button. We can use an ordered data store so we do not have to sort the values ourselves. When the button is clicked, the score for the clicking player is incremented. Meanwhile, another script can keep checking the ordered data store to update a display that shows our top players.

local ods = game:GetService("DataStoreService"):GetOrderedDataStore("HighScore")
local clickDetector = Instance.new("ClickDetector")
clickDetector.Parent = script.Parent
local canClick = true
 
function onMouseClick(Player)
	if not canClick then
		return
	end
	canClick = false
	script.Parent.Color = Color3.new(255, 0, 0)
	ods:IncrementAsync(Player.Name, 1)
	wait(1)
	script.Parent.Color = Color3.new(0, 255, 0)
	canClick = true
end
 
clickDetector.MouseClick:Connect(onMouseClick)
local ods = game:GetService("DataStoreService"):GetOrderedDataStore("HighScore")

function updateBoard(board, data)
	for k,v in pairs(data) do
		local pos = k
		local name = v.key
		local score = v.value
		local nametextbox = board.SurfaceGui:FindFirstChild("Name" .. pos)
		nametextbox.Text = name
		local scoretextbox = board.SurfaceGui:FindFirstChild("Score" .. pos)
		scoretextbox.Text = score
	end	
end

while true do
	-- wrap logic in pcall in case datastore request fails
	local success, message = pcall(function()
		local pages = ods:GetSortedAsync(false, 5)
		
		-- get data for first board
		local data = pages:GetCurrentPage()	
		updateBoard(game.Workspace.Top5ScoreBoard, data)
		
		-- check if another page of data exists
		if not pages.IsFinished then			
			
			-- if so then get data for second board
			pages:AdvanceToNextPageAsync()			
			data = pages:GetCurrentPage()
			updateBoard(game.Workspace.Next5ScoreBoard, data)
		end
	end)
	
	if not success then
		print(message)
	end
	
	wait(60)
end

This place is available here on Roblox. It is not code locked so please feel free to open it in edit mode to better understand how it works.

Tags:
  • datastore
  • coding