如何在Redis中将列表嵌套到结构中以减少顶层?
我想在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值并轻松扩展列表?
回答:
在大多数情况下,SADD
或ZADD
使用流水线命令会更好。如果存在另一个客户端可能会在其间获取密钥的风险,请使用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_key1) "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中将列表嵌套到结构中以减少顶层? 的全部内容, 来源链接: utcz.com/qa/414375.html