文章目錄
在 Redis 中使用 Lua 的 Dictionary
最近幾周一直在趕專案進度,也累積了好幾篇筆記沒有動手,想著如果再不紀錄可能就想不起來當時遇到問題的情境了 ~~~
最近專案主要都是使用 Lua 來存取 Redis,對於過去多數使用 c# 套件的我而言就是東撞個牆西踩個雷的,於是趕緊趁著專案空檔紀錄一下個人使用經驗(方便專案有得抄日後參考?)
雖然在 Lua 之中並沒有 Dictionary,不過還是可以透過 table
來模擬,立馬來看看可以怎麼做吧
基本環境說明
- macOS Majave 10.14.6
Redis 5.0.6
使用 docker 啟動 redis instance
docker run -d -p 6379:6379 redis
ZeroBrane Studio 1.80
情境說明
使用
sets
儲存所有 userIdSADD users 1 3 5
使用
hashes
儲存 user 資料HMSET userdata:1 name "yowko" email "[email protected]" HMSET userdata:3 name "test" email "[email protected]" HMSET userdata:5 name "poc" email "[email protected]"
測試用資料結構
Lua
local allUsersKey="users"
local userdataPrefixKey="userdata"
-- 取得所有 user
local allUsers = redis.call("smembers", allUsersKey)
--逐一處理所有 user
local results = {} for userIndex, userId in ipairs(allUsers) do
-- 單一 user 的 key
local userdataKey=userdataPrefixKey .. ":" .. userId
-- 取得單一 user 的所有屬性值
local getAll= redis.call("HGETALL", userdataKey)
-- 暫存欄位名稱
local tmpSubKey=""
-- 處理所有欄位屬性
local tmpSubData = {} for index,value in ipairs (getAll) do
-- 如果 index 是單數則為欄位名稱,偶數為屬性值
if index % 2 == 1 then
tmpSubKey= value
else
-- 使用名稱設定 table
tmpSubData[tmpSubKey]=value
end
end
-- 將個別 user 的所有屬性存入 table 中
results[userId]=tmpSubData
end
return results
結果
{"1":{"name":"yowko","email":"[email protected]"},"3":{"name":"test","email":"[email protected]"},"5":{"name":"poc","email":"[email protected]"}}
另種實作
測試功能時,發現原本的表示法在實際使用上有些缺點,改一下
Lua
local allUsersKey="users" local userdataPrefixKey="userdata" -- 取得所有 user local allUsers = redis.call("smembers", allUsersKey) --逐一處理所有 user local results = {} for userIndex, userId in ipairs(allUsers) do -- 單一 user 的 key local userdataKey=userdataPrefixKey .. ":" .. userId -- 取得單一 user 的所有屬性值 local getAll= redis.call("HGETALL", userdataKey) -- 暫存欄位名稱 local tmpSubKey="" -- 處理所有欄位屬性 local tmpSubData = {} -- 將 userId 當做 object 的一個屬性 tmpSubData["userId"]=userId for index,value in ipairs (getAll) do -- 如果 index 是單數則為欄位名稱,偶數為屬性值 if index % 2 == 1 then tmpSubKey= value else -- 使用名稱設定 table tmpSubData[tmpSubKey]=value end end -- 將個別 user object 存入 table 中 table.insert(results, tmpSubData) end return results
結果
[{"userId":"1","name":"yowko","email":"[email protected]"},{"userId":"3","name":"test","email":"[email protected]"},{"userId":"5","name":"poc","email":"[email protected]"}]
心得
雖然透過上面的 lua script 可以模擬出 dictionary 的樣子,但實際使用上還是有限制,其中最大的問題就是無法直接輸出 table (以下列出差異)
一般 table (正常輸出)
table.insert(results,userId)
使用 Dictionary (未輸內容)
results[userId]=tmpSubData
至於該如何解決,請待下回筆記分享個人(不知道是不是正確)的做法
參考資訊
文章作者 Yowko Tsai
上次更新 2019-12-09
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。