ServiceStack Redis,如何将Lua表作为列表返回

我正在使用ServiceStack的Redis客户端。我有一个Lua脚本,该脚本用多个Redis调用的结果填充Lua表。我想以某种方式返回此表。我的想法是使用客户端库中的ExecLuaShaAsList方法,并在lua脚本中执行“

return myTable”。它不起作用,我总是返回一个空列表。

如何将lua表返回给Redis客户端?

using (var redisClient = GetPooledRedisClient())

{

var sha1 = redisClient.LoadLuaScript(luaBody);

List<string> theList = redisClient.ExecLuaShaAsList(sha1);

int listLength = theList.Count(); //listLength is always 0 for some reason

}

    private string GetLuaScript(List<CatalogItem> categories, List<CatalogItem> products)

{

string categoriesToAggregate = string.Join("\",\"", categories.Select(c=>c.Name));

categoriesToAggregate = "\"" + categoriesToAggregate + "\"";

string csSearchResult = string.Join("\",\"", products.Select(c => c.Name));

csSearchResult = "\"" + csSearchResult + "\"";

StringBuilder sb = new StringBuilder();

sb.AppendLine("local categoriesToAggregate = {").Append(categoriesToAggregate).Append("} ");

sb.AppendLine("local csSearchResult = {").Append(csSearchResult).Append("} ");

sb.AppendLine("local result = {} ");

sb.AppendLine();

sb.AppendLine("for i=1,#categoriesToAggregate do ");

sb.AppendLine(" result[categoriesToAggregate[i]] = 0 ");

sb.AppendLine();

sb.AppendLine(" for j=1,#csSearchResult do ");

sb.AppendLine(" local fieldValue = redis.call('hget', 'asr:'..csSearchResult[j], categoriesToAggregate[i]) ");

sb.AppendLine(" if fieldValue then ");

sb.AppendLine(" result[categoriesToAggregate[i]] = result[categoriesToAggregate[i]] + fieldValue ");

sb.AppendLine(" end ");

sb.AppendLine(" end ");

sb.AppendLine("end ");

sb.AppendLine();

sb.AppendLine("return cjson.encode(result) ");

return sb.ToString();

}

回答:

从Lua,您需要返回Lua数组或JSON对象。“

myTable”听起来像一个仅在Lua解释器内部有效的句柄。该句柄将在调用后立即清理,因此不会传播到客户端。

编辑:应该 支持一个简单的Lua表/数组。不知道接下来发生了什么,而无需查看脚本。

另请参见此SO 链接,以获取有关Lua脚本原子性的一些额外信息。

希望这会有所帮助,TW

这是OP的原始Lua脚本:

local a={}

for i = 1, 1, 1 do

a["47700415"] = redis.call('hget', 'asr:47700415', 'MDEngines')

a["47700415_000"] = redis.call('hget', 'asr:47700415_000', 'MGEngines')

end

return a

您不能在Lua返回值中返回嵌套值。从ServiceStack函数可以看到,Lua脚本返回一个列表,并且列表没有嵌套。

这里有两种解决方案,一种采用JSON的解决方案会产生少量开销(但编程时可能会更容易,而且非常安全)。

答:使用cjson

local a={}

for i = 1, 1, 1 do

a["47700415"] = redis.call('hget', 'asr:47700415', 'MDEngines')

a["47700415_000"] = redis.call('hget', 'asr:47700415_000', 'MGEngines')

end

return cjson.encode(a)

MsgPack还是一种非常好的紧凑型序列化格式(我们经常使用),可以这样返回:

a-alt:使用cmsgpack

return cmsgpack.pack(a)

b:使用一个简单的数组

local a={}

for i = 1, 1, 1 do

a[1] = "47700415"

a[2] = redis.call('hget', 'asr:47700415', 'MDEngines')

a[3] = "47700415_000"

a[4] = redis.call('hget', 'asr:47700415_000', 'MGEngines')

end

return a

返回:

tw@srv-flux-02:~$ redis-cli -p 14312 EVAL "$(cat ~/tw_luatest.lua)" 0 0

"{\"47700415\":\"Hello\",\"47700415_000\":\"World\"}"

b

tw@srv-flux-02:~$ redis-cli -p 14312 EVAL "$(cat ~/tw_luatest2.lua)" 0 0

1) "47700415"

2) "Hello"

3) "47700415_000"

4) "World"

如您所见,我在中放入了一些虚拟数据HSET

我也可以推荐此链接,那里有一些不错的信息:lua-for-redis-

programmers简介

可以在这里看到一个为Lua dict添加值的好方法:

local fkeys = redis.call('sinter', unpack(KEYS))

local r = {}

for i, key in ipairs(fkeys) do

r[#r+1] = redis.call('hgetall',key)

end

return r

以上是 ServiceStack Redis,如何将Lua表作为列表返回 的全部内容, 来源链接: utcz.com/qa/427468.html

回到顶部