gpt4 book ai didi

lua - ServiceStack Redis,如何将Lua表返回为List

转载 作者:IT王子 更新时间:2023-10-29 05:57:48 25 4
gpt4 key购买 nike

我正在使用 ServiceStack 的 Redis 客户端。我有一个 Lua 脚本,它用几个 Redis 调用的结果填充一个 Lua 表。我想以某种方式归还这张 table 。我的想法是使用客户端库中的 ExecLuaShaAsList 方法,并在 lua 脚本中执行“return myTable”。它不起作用,我总是得到一个空列表。

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

这是我与 Redis 客户端一起使用的 C# 脚本:

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
}

根据以下答案更新提示

LuaBody 是这样创建的:

    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 表/数组应该是 supported .如果不查看脚本,就不确定发生了什么。

另请参阅此 SO link有关 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 会产生轻微的开销(但在编程时可能更容易,并且是 nill-safe)。

a:使用 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 中放置了一些虚拟数据。

我也可以推荐这个链接,里面有一些不错的信息:intro-to-lua-for-redis-programmers

可以看到一种向 Lua 字典添加值的好方法 here :

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

关于lua - ServiceStack Redis,如何将Lua表返回为List,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22287334/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com