从redis散列字段值中删除特定值

pftdvrlh  于 2023-02-28  发布在  Redis
关注(0)|答案(1)|浏览(181)

我有redis散列,我想删除字段的特定值。

127.0.0.1:6379> hset abc 12 34,121
(integer) 1
127.0.0.1:6379> hgetall abc
1) "12"
2) "34,121"

我只想从值中删除121。
我知道hdel命令删除字段,但不删除字段的特定值。

127.0.0.1:6379> hdel abc 12
(integer) 1
127.0.0.1:6379> hgetall abc
(empty array)

这删除了用于散列的整个字段。

xghobddn

xghobddn1#

Redis中的散列存储Redis字符串。Redis不知道值包含逗号分隔的数字列表。它只看到一个字符串。你需要把值拉出来,在代码中修改它,然后把它写回去。
如果你想原子地完成这件事,你需要考虑使用transactions--它给予你一个乐观的锁定机制--或者写一个Lua脚本。
首先,观察键abc,如果在事务处理过程中这个键被改变了,事务处理将会失败,你需要在代码中处理它。

127.0.0.1:6379> WATCH abc
OK

现在,您需要从键中获取字段的值,并编写代码来解析它并删除有问题的值:

127.0.0.1:6379> HGET abc 12
"34,121"

要写出该值并确保没有其他人执行相同的操作,请使用MULTI启动一个事务,HSET该字段的新值,然后调用EXEC:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> HSET abc 12 34
QUEUED
127.0.0.1:6379(TX)> EXEC
1) (integer) 0

如果没有人修改abc,EXEC应该返回你已经排队的命令的结果,在这个例子中是添加到哈希的字段的数目。如果有人 * 已经 * 修改了键abc,它将返回(nil),你需要在代码中重试。
如果可以的话,你可以考虑使用RedisJSON将这些值作为JSON存储在Redis中,然后,你可以使用JSONPath查询来修改数组:

127.0.0.1:6379> JSON.SET abc $ '{ "12": [ 34, 121 ]}'
OK
127.0.0.1:6379> JSON.DEL abc "$.12[?(@ == 121)]"
(integer) 1
127.0.0.1:6379> JSON.GET abc
"{\"12\":[34]}"

更易于编码,并且无需对事务或Lua进行干预。

相关问题