skip to Main Content

I’m using Redis sorted set to keep some values in order. for example:

score | data
0     |  a
1     |  b
2     |  c
3     |  d

In some situations of my app, I have to remove some of the entries. for example, I delete scores 1 and 2 members:

score | data
0     |  a
3     |  d

I want to change the above to:

score | data
0     |  a
1     |  d

How can I do this?

please help, thanks in advance.

3

Answers


  1. Chosen as BEST ANSWER

    After searching and hard work, I found the solution.

    You can use Lua script and EVAL command:

    EVAL 
    "
    redis.call('ZREMRANGEBYSCORE', KEYS[1], KEYS[2], KEYS[2]);
    local otherMembers = redis.call('ZRANGEBYSCORE', KEYS[1], KEYS[2], 1/0);
    for k, v in ipairs(otherMembers) do
    redis.call('ZINCRBY', KEYS[1], -1], v);
    "
    2 key index;
    

  2. I think it’s not possible to use a sorted list in Redis like an indexed array.

    If you want to have a sorted list with a sequential score you should take care of it yourself so after every delete, you can overwrite your sorted list with new scores.

    Login or Signup to reply.
  3. It seems that you don’t need the score, instead, you need the rank.

    You can keep a monotonically increasing counter, which starting from 0, and each time when you need to add an element to the set, call incr on the counter to get a score, and insert the element into the set. So that, each new element will always has the largest score, i.e. new element will rank lower than old elements.

    127.0.0.1:6379> incr counter
    (integer) 1
    127.0.0.1:6379> zadd set 1 a
    (integer) 1
    127.0.0.1:6379> incr counter
    (integer) 2
    127.0.0.1:6379> zadd set 2 b
    (integer) 1
    127.0.0.1:6379> incr counter
    (integer) 3
    127.0.0.1:6379> zadd set 3 c
    (integer) 1
    127.0.0.1:6379> incr counter
    (integer) 4
    127.0.0.1:6379> zadd set 4 d
    

    You can use ZREMRANGEBYRANK to remove elements, and ZRANK to get the rank of each element (the rank always start from 0).

    127.0.0.1:6379> zremrangebyrank set 1 2
    (integer) 2                              <------- remove b and c
    127.0.0.1:6379> zrank set a
    (integer) 0
    127.0.0.1:6379> zrank set d
    (integer) 1
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search