更新REDIS/jedis中排序集合中所有成员的分数

10

如何使用REDIS以最佳方式递增中等大小的排序集?(最好使用Java驱动程序JEDIS)集合中大约有100-200K条记录。我想将它们的分数按给定的双倍数字递增。

after

如果你想以最佳方式递增一个中等大小的排序集,可以使用REDIS(最好使用Java驱动程序JEDIS)。这个集合中大约有100-200K条记录。你可以通过给定的双倍数字来递增它们的分数。

1 a
2 b
3 c

after (增加1)

2 a
3 b
4 c

我想到的唯一可能的解决方案是:
  1. 通过网络获取所有已排序集合(例如A)的内容。(REDIS -> 应用程序)。
  2. 创建一个管道,在循环中使用ZADD或ZINCRBY将它们逐个增加到同一集合A中。
  3. 然后执行该管道。
还有其他/更好的方法吗?

更新

以下是如何使用EVAL和Lua在REDIS中进行for循环以递增所有已排序集合成员的方法。
local members = redis.call('zrange',KEYS[1],0,-1)
for i, member in ipairs(members) do
    redis.call('zincrby',KEYS[1],inc,member)
end

将此保存为字符串并使用您的驱动程序(在本例中为Java)运行eval。执行不返回任何内容。
使用Jedis。
// script is the script string
// 1 is the number of keys- keep it this way for this script
// myzset is the name of your sorted set
// 1.5 is the increment, you can use +/- values to inc/dec.
jedis.eval(script, 1, "myzset", "1.5");
1个回答

3

客户端和Redis之间的通信可能需要很长时间。为了避免这种情况,您可以使用"SET类型"的有序集合副本。例如,假设您有一个有序集合"key1":

1 a
2 b
3 c

而且你还有一个名为“key2”的集合:

a, b, c

您可以轻松实现增量:

def increase_sorted_set(increment = 1)
  redis.ZINTERSTORE("key1", 2, "key1", "key2", "WEIGHTS", "1", increment)
end

Redis会为非排序集合key2中的每个成员设置默认分数1

例如:

redis 127.0.0.1:6379> ZADD key1 1 a 2 b 3 c
(integer) 3
redis 127.0.0.1:6379> SADD key2 a b c
(integer) 3
redis 127.0.0.1:6379> ZINTERSTORE key1 2 key1 key2 WEIGHTS 1 7
(integer) 3
redis 127.0.0.1:6379> ZRANGE key1 0 -1 WITHSCORES
1) "a"
2) "8"
3) "b"
4) "9"
5) "c"
6) "10"

我不知道ZINTERSTORE可以将SET作为参数。我该如何创建一个排好序的集合的“SET类型”副本? - Onur Günduru
你需要通过网络获取key1的所有元素(ZRANGE key1 0 -1),并使用SADD将这些元素添加到key2中,或者使用脚本(http://redis.io/commands/eval)在服务器端执行此操作。之后,当你想要向key1添加新元素时,只需同时将该元素添加到key2中即可。 - luin
我会检查EVAL。复制该集合可能是一个快速解决方案。然而,我的资源有限,我有很多类似的集合。此外,我需要为删除操作和添加操作复制代码。谢谢,我会接受这个解决方案直到未来的版本 :) 仍然希望有更好的方法。 - Onur Günduru
@luin,一个改进的方法是,我们可以使用zunionstore而不是zinterstore。这样,我们就不必创建另一个具有完全相同元素数量的排序集合了。 - Mukul Bansal

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