gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 06:41:25 26 4
gpt4 key购买 nike

我想在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.

我想我可以创建一个新 key 并使用 zadd维护一个列表。但是我想尽量减少 key 的数量。这是因为一旦用户退出,我需要快速使 key 无效。将 key 保持在最低限度可以帮助我

1)快速驱逐 key

2)避免错误,因为有更少的键来保持标签

有什么办法可以将列表保留在 redis 值中并轻松扩展列表?

最佳答案

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

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

关于“快速驱逐 key ”,请务必使用 UNLINK而不是 DEL .

如果您选择字符串化,这里是如何使用 Lua 在哈希字段中以原子方式支持插入和删除到 JSON 编码的数组。和 Lua CJSON library :

插入 :

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\"]"

关于redis - 如何将列表嵌套到 Redis 中的结构中以减少顶层?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59979347/

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