使用Redis更新有序集合

4

目前我正在尝试更新一个有序集合成员。查看文档,使用ZADD可以更新成员,如果它的分数已经存在。然而,在尝试更新成员时使用此代码,

db.zadd("users", parseInt(key, 10) + 1, JSON.stringify(newData));

即使已经存在一个分数,也可以添加新的条目!如何使用Redis更新排序集成员?

3个回答

8

ZADD命令将替换已存在成员的分数,只要键和成员在条目之间匹配:

redis localhost:6379> ZADD test-key 40 blah
(integer) 1
redis localhost:6379> ZRANGE test-key 0 -1 WITHSCORES
1) "blah"
2) "40"
redis localhost:6379> ZADD test-key 45 blah
(integer) 0
redis localhost:6379> ZRANGE test-key 0 -1 WITHSCORES
1) "blah"
2) "45"

也许您在ZADD命令间使用了不同的键或成员?

谢谢你的答复!我想更新分数(数字标识符)的现有成员(值)。经过一些测试,我发现唯一的方法是删除旧记录并重新上传其新版本。唉,我希望 Redis 能够添加更新成员(如果分数相同)的功能! - derek_duncan
一个排序集合可以容纳多个具有相同分数的成员。您可以使用新分数更新成员,但是使用新成员更新分数没有意义,因为不清楚要删除什么。如果您只想添加具有给定分数的新成员并删除所有当前具有该分数的成员,则可以编写Lua脚本来实现此目的。 如果您详细说明用例,我可以给您更好的答案。 - Eli
当我找到我的记录时,我只是将其数据保存为JSON,然后删除它。更新我的JSON对象后,我使用相同的分数重新上传它。 - derek_duncan
你将如何用不同的值替换“blah”? - Pratik Joshi

5

@Eli已经解释了如何更新元素分数,现在zadd添加了新选项,由@ZettaCircl解释,并且我将使用分数和元素的示例来解释如何更新元素

  1. NX = 添加新元素
  2. XX = 更新元素

将三个国家添加到排序集中

 127.0.0.1:6379> zadd country nx 1 'pakistan' // nx = add new element
(integer) 1
127.0.0.1:6379> zadd country nx 2 'turkey'
(integer) 1
127.0.0.1:6379> zadd country nx 3 'UK'
(integer) 1

获取带分数的国家

127.0.0.1:6379> zrange country 0 10 withscores
1) "pakistan"
2) "1"
3) "turkey"
4) "2"
5) "UK"
6) "3"

更新国家

使用分数将元素 "Pakistan" 的国家名称更新为新名称

127.0.0.1:6379> zadd country xx ch 1 'islamic republic of pakistan'
(integer) 0 // 0 means not updated

使用 元素名称 ('pakistan') 更新巴基斯坦的国家分数。

127.0.0.1:6379> zadd country xx ch 4 'pakistan'
(integer) 1 // updated successfully 

获取带有分数的国家

在这里,我们只更新了分数。

127.0.0.1:6379> zrange country 0 10 withscores
1) "turkey"
2) "2"
3) "UK"
4) "3"
5) "pakistan"
6) "4" // score updated

结论

我们可以使用元素名称仅更新有序集中的分数。


如何更新元素

首先,我们需要移除巴基斯坦。

127.0.0.1:6379> zrem country pakistan
(integer) 1 // removed successfully

获取带有分数的国家列表

127.0.0.1:6379> zrange country 0 10 withscores
1) "turkey"
2) "2"
3) "UK"
4) "3"

新增巴基斯坦并修改名称

在按国家排序的集合中添加新元素,包括新名称和之前的分数。

127.0.0.1:6379> zadd country nx 1 'islamic republic of pakistan'
(integer) 1

获取带有分数的国家

127.0.0.1:6379> zrange country 0 10 withscores
1) "islamic republic of pakistan"
2) "1"
3) "turkey"
4) "2"
5) "UK"
6) "3"

结论

首先,我们需要删除元素,然后将新元素添加到已排序集合中。


1
似乎自你2013年的回答以来,文档已经发生了变化。
ZADD options (Redis 3.0.2 or greater)
ZADD supports a list of options, specified after the name of the key and before the first score argument. Options are:

XX: Only update elements that already exist. Never add elements.
NX: Don't update already existing elements. Always add new elements.
CH: Modify the return value from the number of new elements added, to the total number of elements changed (CH is an abbreviation of changed). Changed elements are new elements added and elements already existing for which the score was updated. So elements specified in the command line having the same score as they had in the past are not counted. Note: normally the return value of ZADD only counts the number of new elements added.
INCR: When this option is specified ZADD acts like ZINCRBY. Only one score-element pair can be specified in this mode.

https://redis.io/commands/zadd可以了解到ZADD的行为。根据你的回答,选项XX会起作用。因此可以写成:

db.zadd("users", XX, parseInt(key, 10) + 1, JSON.stringify(newData));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接