Reproduction Steps
- Save multiple key value pair data into your DataStore where the prefix in the key is the same i.e. “flower…”
Saving data; example script.
local DS = game:GetService("DataStoreService")
local KDS = DS:GetDataStore("FlowerLexemes")
local fakeDataImport = {
["flowerpot"] = 1,
["flowerface"] = 2,
["flowermate"] = 3,
["flowerfind"] = 4,
["flowerfist"] = 5,
["flowerman"] = 6,
["flowertask"] = 7,
["flowerthrow"] = 8,
["flowercrude"] = 9,
["flowerbase"] = 10,
}
for name, weight in pairs(fakeDataImport) do
local success, errorMessage = pcall(function()
print(
string.format(
'Importing key: %s with weight: %d',
name,
weight
)
)
KDS:SetAsync(name, weight)
end)
if success then
print(
string.format(
'Imported key: %s successfully!',
name
)
)
else
warn(errorMessage)
end
end
-
Use ListKeysAsync with a prefix and a limit to retrieve the pages object.
local myPageObject = KDS:ListKeysAsync("flower", 5)
-
Iterate over the page object.
Retrieving data; example script.
local myPageObject = KDS:ListKeysAsync("flower", 5)
-- Reformat pages as tables
local function pagesToTable(pages)
local items = {}
while true do
table.insert(items, pages:GetCurrentPage())
if pages.IsFinished then
break
end
print("---- AdvanceToNextPageAsync ----")
pages:AdvanceToNextPageAsync()
end
return items
end
local function iterPageItems(pages)
local contents = pagesToTable(pages)
-- Track the current page number starting at 1
local pageNum = 1
-- Get last page number so we don't iterate over it
local lastPageNum = #contents
-- for will resume this coroutine until there's nothing to go through
return coroutine.wrap(function ()
-- Loop until page number is greater than last page number
while pageNum <= lastPageNum do
-- Go through all the entries of the current page
for _, item in ipairs(contents[pageNum]) do
-- Pause loop to let developer handle entry and page number
coroutine.yield(item, pageNum)
end
pageNum += 1
end
end)
end
for item, pageNo in iterPageItems(myPageObject) do
print(
string.format(
'Page: %d has key: %s',
pageNo,
item.KeyName
)
)
end
Full script right here:
local DS = game:GetService("DataStoreService")
local KDS = DS:GetDataStore("FlowerLexemes")
local fakeDataImport = {
["flowerpot"] = 1,
["flowerface"] = 2,
["flowermate"] = 3,
["flowerfind"] = 4,
["flowerfist"] = 5,
["flowerman"] = 6,
["flowertask"] = 7,
["flowerthrow"] = 8,
["flowercrude"] = 9,
["flowerbase"] = 10,
}
for name, weight in pairs(fakeDataImport) do
local success, errorMessage = pcall(function()
print(
string.format(
'Importing key: %s with weight: %d',
name,
weight
)
)
KDS:SetAsync(name, weight)
end)
if success then
print(
string.format(
'Imported key: %s successfully!',
name
)
)
else
warn(errorMessage)
end
end
local myPageObject = KDS:ListKeysAsync("flower", 5)
-- Reformat pages as tables
local function pagesToTable(pages)
local items = {}
while true do
table.insert(items, pages:GetCurrentPage())
if pages.IsFinished then
break
end
print("---- AdvanceToNextPageAsync ----")
pages:AdvanceToNextPageAsync()
end
return items
end
local function iterPageItems(pages)
local contents = pagesToTable(pages)
-- Track the current page number starting at 1
local pageNum = 1
-- Get last page number so we don't iterate over it
local lastPageNum = #contents
-- for will resume this coroutine until there's nothing to go through
return coroutine.wrap(function ()
-- Loop until page number is greater than last page number
while pageNum <= lastPageNum do
-- Go through all the entries of the current page
for _, item in ipairs(contents[pageNum]) do
-- Pause loop to let developer handle entry and page number
coroutine.yield(item, pageNum)
end
pageNum += 1
end
end)
end
for item, pageNo in iterPageItems(myPageObject) do
print(
string.format(
'Page: %d has key: %s',
pageNo,
item.KeyName
)
)
end
- Observe that the output incorrectly paginates keys:
Expected Behavior
ListKeysAsync should be able to return all pages with the keys matching the prefix within the limit. If I have 10 “flower…” keys with the “flower” prefix set and a limit of 5 as my query parameter, upon iterating it should find only 2 pages with 5 keys.
Actual Behavior
ListKeysAsync incorrectly returns the keys in separate pages instead of following the query parameter “pageSize” rule. Occasionally it puts only 2 keys into a single page but most of the time 1 key per page is returned. Full thread where I first noticed the bug: ListKeysAsync does not work? - Help and Feedback / Scripting Support - DevForum | Roblox
Workaround
None
Issue Area: Engine
Issue Type: Other
Impact: High
Frequency: Constantly
Date First Experienced: 2023-01-25 21:00:00 (+02:00)