Lua Redis:将值中的键引用展开为其值
我是redis的新手。我有一个CMS,它以如下结构将JSON输出到redis:Lua Redis:将值中的键引用展开为其值,lua,redis,Lua,Redis,我是redis的新手。我有一个CMS,它以如下结构将JSON输出到redis: partial:1 => {id: 1, title: 'Foo1', ...} partial:2 => {id: 2, title: 'Foo2', ...} partial:3 => {id: 3, title: 'Foo3', ...} page:home => { id: 'Homepage', teaser1: 'partial:1', teaser2: 'pa
partial:1 => {id: 1, title: 'Foo1', ...}
partial:2 => {id: 2, title: 'Foo2', ...}
partial:3 => {id: 3, title: 'Foo3', ...}
page:home => {
id: 'Homepage',
teaser1: 'partial:1',
teaser2: 'partial:2',
teaser3: {type: Slider, content: 'partial:3'}
}
{
id: 'Homepage',
teaser1: {id: 1, title: 'Foo1', ...},
teaser2: {id: 2, title: 'Foo2', ...},
teaser3: {type: Slider, content: {id: 3, title: 'Foo3', ...}
}
因此,JSON可以包含其他redis键,这些键在其结构中符合特定的命名方案。我想要的是一种查询redis的方法,这样当我获得页面:home
-键时,json中对其他键的引用会被“扩展”为各自的值,如下所示:
partial:1 => {id: 1, title: 'Foo1', ...}
partial:2 => {id: 2, title: 'Foo2', ...}
partial:3 => {id: 3, title: 'Foo3', ...}
page:home => {
id: 'Homepage',
teaser1: 'partial:1',
teaser2: 'partial:2',
teaser3: {type: Slider, content: 'partial:3'}
}
{
id: 'Homepage',
teaser1: {id: 1, title: 'Foo1', ...},
teaser2: {id: 2, title: 'Foo2', ...},
teaser3: {type: Slider, content: {id: 3, title: 'Foo3', ...}
}
这可能吗?如何实现?我不知道Redis,但也许这对您有用:
local T=[[
partial:1 => {id: 1, title: 'Foo1', ...}
partial:2 => {id: 2, title: 'Foo2', ...}
partial:3 => {id: 3, title: 'Foo3', ...}
page:home => {
id: 'Homepage',
teaser1: 'partial:1',
teaser2: 'partial:2',
teaser3: {type: Slider, content: 'partial:3'}
}
]]
local D={}
for k,v in T:gmatch("(%w+:%w+)%s*=>%s*(%b{})") do
D[k]=v
end
print((T:gsub("'(.-)'",D)))
对。这是很有可能的。以下是一种有效的方法:
--Function to Convert a given hash name (e.g: partial:1..n, page:home) to a lua table
local function hgetall(a)local b=redis.call('HGETALL',a)local c={}local d;for e,f in ipairs(b)do if e%2==1 then d=f else c[d]=f end end;return c end
--Function to check if the given value conforms with a naming scheme,
-- if so convert it to a lua table; otherwise return the values as is.
local function evaluate_hash(value)
local pattern = "partial:%d+"
if string.match(value, pattern) then
return hgetall(value)
else
return value
end
end
--Function to convert a given hash_name to a lua table,
-- iterate all elements and convert them to lua table if necessary
-- returns the table as a json object
local function expand(hash_name)
local obj_table = hgetall(hash_name)
for k, val in pairs(obj_table) do
obj_table[k] = evaluate_hash(val)
end
return cjson.encode(obj_table)
end
local page = KEYS[1]
local json_result = expand(page) or {}
redis.log(redis.LOG_NOTICE, tostring(json_result))
return json_result
控制台测试:
redis cli-c hmset“部分:1”id 1标题1
嗯
redis cli-c hmset“部分:2”id 2标题2
嗯
redis cli-c hmset“页面:主页”“id”“主页”“摘要1”“摘要2”“部分:2”
嗯
redis cli EVAL“$(cat redis_expand_as_json.lua)”1'页面:主页'
这与Lua有什么关系?因为Redis可以在其eval方法中执行Lua脚本,所以我认为这可能是解决这个问题的一种可能的方法。