当前位置: 首页 > 面试题库 >

如何在Redis中将列表嵌套到结构中以减少顶层?

高钱青
2023-03-14
问题内容

我想在Redis中维护一些元数据。

meta_key = build_key()
meta_data = {
    "user": 12345,
    "tag": "D12321341234123",
    }
res = redis_sip.hmset(meta_key, meta_data)

它按预期工作。

现在,我想在此meta_data结构中保留一个列表,并能够将元素添加到列表中。

例如:

meta_data = {
    "user": 12345,
    "tag": "D12321341234123",
    "items": []
    }

但这立即引发异常:

redis.exceptions.DataError: Invalid input of type: 'list'. Convert to a byte, string or number first.

我认为我可以创建一个新密钥并用于zadd维护列表。但是我想尽量减少密钥的数量。这是因为用户注销后,我需要快速使密钥失效。将密钥保持在最低限度可以帮助我

1)快速移出按键

2)避免出现错误,因为用于保持制表符的键较少

有什么办法可以使列表保持redis值并轻松扩展列表?


问题答案:

在大多数情况下,SADDZADD使用流水线命令会更好。如果存在另一个客户端可能会在其间获取密钥的风险,请使用MULTI /
EXEC事务,从而获得不完整的对象。

在某些情况下,在哈希字段中对列表进行字符串化可能是合理的。

关于“快速退出键”,请确保使用UNLINK代替DEL

如果选择进行字符串化,则以下是使用Lua和Lua
CJSON库
在散列字段中自动支持插入和删除到JSON编码数组的方法:

插入

local items = cjson.decode(redis.call('HGET', KEYS[1], 'items'))
table.insert(items, ARGV[1])
return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))

按值删除

local items = cjson.decode(redis.call('HGET', KEYS[1], 'items'))
local pos = -1;
for i, v in ipairs(items) do
    if ARGV[1] == v then
        pos = i
        break
    end
end
if pos == -1 then
    return -1
else
    table.remove(items, pos)
    return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))
end

用法示例

> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "{}"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n table.insert(items, ARGV[1]) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))" 1 meta_key value1
(integer) 0
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value1\"]"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n table.insert(items, ARGV[1]) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))" 1 meta_key value2
(integer) 0
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value1\",\"value2\"]"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n local pos = -1; \n for i, v in ipairs(items) do \n     if ARGV[1] == v then \n     pos = i \n     break \n end \n end \n if pos == -1 then \n     return -1 \n else \n     table.remove(items, pos) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items)) \n end" 1 meta_key value1
(integer) 0
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value2\"]"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n local pos = -1; \n for i, v in ipairs(items) do \n     if ARGV[1] == v then \n     pos = i \n     break \n end \n end \n if pos == -1 then \n     return -1 \n else \n     table.remove(items, pos) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items)) \n end" 1 meta_key value3
(integer) -1
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value2\"]"


 类似资料:
  • 我的问题基本上归结为将列表减少为链表,但从reduce函数推断出的类型似乎不正确。 我的列表如下所示 我希望reduce函数在每个reduce步骤中都能做到这一点 然而,减少函数似乎认为这不起作用,因为我猜它不认为身份是节点。 这是我的密码。 我做错了什么? 在接受答案后编辑,我的代码如下所示: 现在打印出来了 我仍然不知道为什么Java不能告诉减少函数的第三个参数是不必要的,它永远不会被调用,但

  • 我试图从API调用中检索数据并将其传递给另一个服务。我收到的数据是在一个特定的JSON结构,我想把它映射到一个结构,但没有多层次的数据。我尝试了点符号来访问更深的值,但它不起作用。 基本上,我试图得到一个包含一系列“问题”(key、self、description)的结构,但没有“fields.description”结构。 JSON: 结构: 预期/期望的结构: 有可能吗?如果是,怎么做?使用嵌

  • 问题内容: 我经常遇到这样的情况:我要存储的信息比Redis任何简单数据结构所能容纳的信息都要复杂。我仍然想使用Redis,但是我想知道人们在理想情况下是否希望使用嵌套结构使用任何标准替代方案? 问题答案: 您基本上有两种策略: 您可以序列化复杂对象并将其存储为字符串。我们建议使用json或msgpack作为序列化格式。这很容易从大多数客户端语言进行操作。如果需要服务器端访问,则服务器端的Lua脚

  • 问题内容: 嗨,我是Golang的新手,请帮助我。我已经在结构内部定义了一个结构。但是,当我尝试初始化主结构时出现错误。 我得到的错误是:不能在字段值中使用(类型接口{})作为类型结构:需要类型声明。 请提出一种初始化DetailsFilter的方法。我尝试执行在Golang中初始化嵌套结构中描述的方法,但即使这样也不起作用。 问题答案: 不幸的是,如果结构字段的类型是匿名结构,则 _在构造时_只

  • 问题内容: 因此,我正在研究UVA问题,并且我有4个嵌套循环来遍历多边形列表(每个多边形都包含一个点列表,其中每个点都包含一个整数x和y来表示其坐标,即,polygon [0]是一个点,其坐标为面[0] .x和面[0] .y)。 我试图减少程序中for循环的数量,以使其更高效并降低运行时间。我的代码如下: 我尝试通过使用itertools.product使其变得更加高效,如下所示: 无论如何,我的

  • 问题内容: 我有一个嵌套列表,例如: 在将此列表插入数据库之前,我想在新列的每一行中添加一个具有相同值的“列”,例如: 例如,当原始的嵌套列表可能有数百行时,什么是最好的方法? 问题答案: 为什么不更改原始列表(如果您要这样做):