Redis: set all scores in a sorted set to a given value

132 Views Asked by At

I am using Redis to keep user scores sorted but I need to set all scores a given value, e.g. 100, periodically.

So far what I found is to use ZUINIONSTORE command to multiply values with a weight and this does not solve my case precisely.

Is there a proper way to accomplish this?

It does not matter to do this operation in-place or copying to another sorted set.

Example flow:

redis> ZADD zset 101 "one"
(integer) 1
redis> ZADD zset 102 "two"
(integer) 1
redis> ZADD zset 103 "three"
(integer) 1
redis> ZUNIONSTORE zset 1 zset WEIGHTS 0 // sets all scores to 0
(integer) 3
1

There are 1 best solutions below

0
dizzyf On

You could potentially use two calls. Maintain a separate set of scores that stay static at 100. Set the weight to zero like you do above, then call ZUNIONSTORE again with the SUM aggregation. Perhaps something like this:

User set:

127.0.0.1:6379> ZADD userset 101 "user1"
(integer) 1
127.0.0.1:6379> ZADD userset 102 "user2"
(integer) 1
127.0.0.1:6379> ZADD userset 103 "user3"
(integer) 1
127.0.0.1:6379> ZRANGE userset 0 -1 WITHSCORES
1) "user1"
2) "101"
3) "user2"
4) "102"
5) "user3"
6) "103"

100 set:

127.0.0.1:6379> ZADD 100set 100 "user1"
(integer) 1
127.0.0.1:6379> ZADD 100set 100 "user2"
(integer) 1
127.0.0.1:6379> ZADD 100set 100 "user3"
(integer) 1
127.0.0.1:6379> ZRANGE 100set 0 -1 WITHSCORES
1) "user1"
2) "100"
3) "user2"
4) "100"
5) "user3"
6) "100"

Actions Start Here

Then clear the user set, and then SUM aggregate with the other:

127.0.0.1:6379> ZUNIONSTORE userset 1 userset WEIGHTS 0
(integer) 3
127.0.0.1:6379> ZUNIONSTORE userset 3 userset 100set SUM
(integer) 3
127.0.0.1:6379> ZRANGE userset 0 -1 WITHSCORES
1) "user1"
2) "100"
3) "user2"
4) "100"
5) "user3"
6) "100"

EDIT: if the scores were guaranteed to be >100 then you could alternatively just do the following and save a call:

127.0.0.1:6379> ZUNIONSTORE userset 3 userset 100set MIN
(integer) 3