redis zadd:仅在分数较低时更新

ilmyapht  于 2021-06-09  发布在  Redis
关注(0)|答案(2)|浏览(476)

我需要为我添加到集合中的每个键存储最低的分数,但是当我这样做时 ZADD ,即使分数更高,redis也会用新值覆盖分数。

ZADD myorderset 1 'one' 2 'two' 3 'three'
(integer) 3

ZRANGE myorderset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"

ZADD myorderset 5 'three'
(integer) 0

ZRANGE myorderset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "5"

在本例中,我需要不更新键“3”,因为新的分数(5)高于现有的分数(3)。有没有一种方法可以在本地完成这项工作,或者我需要在lua中创建一个脚本?
我一直在研究 ZADD 修饰语 (XX, NX, CH) 但没有一个能满足我的需要。
非常感谢你!

cotxawn7

cotxawn71#

这个cas用例的lua脚本将是最简单和惯用的解决方案:

127.0.0.1:6379> ZADD myorderset 1 'one' 2 'two' 3 'three'
(integer) 3
127.0.0.1:6379> EVAL "local s = redis.call('ZSCORE', KEYS[1], ARGV[2]) if not s or s > ARGV[1] then redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2]) end" 1 myorderset 5 'three'
(nil)
127.0.0.1:6379> ZRANGE myorderset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
127.0.0.1:6379> EVAL "local s = redis.call('ZSCORE', KEYS[1], ARGV[2]) if not s or s > ARGV[1] then redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2]) end" 1 myorderset 2 'three'
(nil)
127.0.0.1:6379> ZRANGE myorderset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "three"
4) "2"
5) "two"
6) "2"
uqdfh47h

uqdfh47h2#

没有一个命令或命令选项可以同时执行这两个操作。你可以使用 ZSCOREZADD (卢阿语)。或者(“这是/看起来像过度设计”)你可以使用 ZUNIONSTOREaggregate 期权 MIN .
AGGREGATE 选项,可以指定如何聚合联合的结果。此选项默认为sum,其中元素的分数在其存在的输入之间求和。当此选项设置为 MIN 或者 MAX ,结果集将包含元素在其存在的输入中的最小或最大分数。

127.0.0.1:6379> ZADD base 1 a 2 b 5 c
(integer) 3
127.0.0.1:6379> ZADD new 3 c
(integer) 1
127.0.0.1:6379> ZUNIONSTORE base 2 base new AGGREGATE MIN
(integer) 3
127.0.0.1:6379> DEL new
(integer) 1
127.0.0.1:6379> ZRANGE base 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"
5) "c"
6) "3"
127.0.0.1:6379> ZADD new 5 b
(integer) 1
127.0.0.1:6379> ZUNIONSTORE base 2 base new AGGREGATE MIN
(integer) 3
127.0.0.1:6379> DEL new
(integer) 1
127.0.0.1:6379> ZRANGE base 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"
5) "c"
6) "3"
127.0.0.1:6379>

如果你愿意,
您可以生成 new 在应用程序级别用随机字符串设置名称
EXPIRE 对于这个新的集合,不需要 DELZUNIONSTORE ,最终将过期。
它可以在 MULTI / EXEC 在一次交易中。

相关问题