Redis ZADD:仅在分数较低时更新
我需要为我添加到集合中的每个关键点存储最低分数,但是当我执行Redis ZADD:仅在分数较低时更新,redis,Redis,我需要为我添加到集合中的每个关键点存储最低分数,但是当我执行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
时,即使分数更高,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
时,结果集将包含元素在其存在的输入中的最小或最大分数
如果你愿意
- 您可以在应用程序级别生成带有随机字符串的
集合名称new
- 将
放入此新设置,在EXPIRE
之后,无需手动ZUNIONSTORE
新密钥,它最终将过期DEL
- 它可以在单个事务中的
/MULTI
中完成EXEC
- 没有一个命令或命令选项可以同时执行这两项操作。您可以将
ZSCORE
与ZADD
组合使用(在lua中)。或者(“它是/看起来是过度设计的”)您可以将ZUNIONSTORE
与aggregate
选项MIN
一起使用
使用AGGREGATE
选项,可以指定如何聚合联合的结果。此选项默认为SUM,其中元素的分数在其存在的输入中求和。当此选项设置为MIN
或MAX
时,结果集将包含元素在其存在的输入中的最小或最大分数
如果你愿意
- 您可以在应用程序级别生成带有随机字符串的
集合名称new
- 将
放入此新设置,在EXPIRE
之后,无需手动ZUNIONSTORE
新密钥,它最终将过期DEL
- 它可以在单个事务中的
/MULTI
中完成EXEC
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"
此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"
你试过eval lua脚本吗?@Gawain是的,我在lua中有一个脚本可以进行检查,并且只在分数较低时更新,但我想知道是否有可能以本机方式执行此操作,我没有找到任何命令来执行此操作。谢谢。你试过eval lua脚本吗?@Gawain是的,我在lua中有一个脚本可以进行检查,只有分数较低时才会更新,但我想知道是否有可能以本机方式执行此操作,我没有找到任何命令来执行此操作。谢谢。谢谢,我终于用了Lua脚本。谢谢,我终于用了Lua脚本。谢谢,我终于用了Lua脚本。谢谢,我终于用了Lua脚本。