[英]Redis ZADD: update only when score is lower
我需要为添加到集合中的每个键存储最低分数,但是当我执行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"
在示例情况下,我需要不更新键“三”,因为新分数高于 (5) 高于现有分数 (3)。 有没有办法在本地做到这一点,还是我需要在 Lua 中创建一个脚本?
我一直在研究ZADD
修饰符(XX, NX, CH)
但没有一个能满足我的需要。
非常感谢!
没有单一的命令或命令选项可以同时执行此操作。 您可以将ZSCORE
与ZADD
(在 lua 中)结合使用。 或者(“它/看起来像是过度设计”)您可以将ZUNIONSTORE
与aggregate
选项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
放到这个新的集合上, ZUNIONSTORE
之后不需要手动DEL
新的密钥,它最终会过期。MULTI
/ EXEC
中完成。此 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"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.