如何将列表嵌套到Redis中的结构中以减少顶级? [英] How to nest a list into a structure in Redis to reduce top level?

查看:51
本文介绍了如何将列表嵌套到Redis中的结构中以减少顶级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在redis中维护一些元数据.

I want to maintain some meta data in redis.

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

它按预期工作.

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

Now I want to keep a list in this meta_data structure and be able to add element to the list.

例如:

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

但它马上抛出异常:

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

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

I reckon I can create a new key and use zadd to maintain a list. However I would like to minimise the number of key. It is because I need to quickly invalidate the keys once the user signs out. Keeping the keys to bare minimum can help me to

1) 快速驱逐钥匙

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

2) avoid error because there are less keys to keep a tab on

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

Is there any way I can keep a list in a redis value and easily expand the list?

推荐答案

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

In most cases, SADD or ZADD with pipelining commands will be better. Use a MULTI/EXEC transaction if there is risk another client may get the key in between, therefore getting an incomplete object.

在某些情况下,将哈希字段中的列表字符串化可能是合理的.

Stringify the list in a hash-field may be justifiable in a few cases.

关于快速驱逐密钥",请确保使用 UNLINK 而不是 DEL.

Regarding 'Quickly evict the keys', make sure to use UNLINK instead of DEL.

如果您选择字符串化,这里是如何使用 LuaLua CJSON 库:

If you choose to stringify, here is how to atomically support insert and remove to a JSON-encoded array in a hash field using Lua and 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中的结构中以减少顶级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆