**Tags**

I’ve been using Redis extensively in a project in the last couple of weeks. And this post is on a small trick I had to resort to while using sorted sets. If you don’t already know, the rank of an element in a Redis sorted set is its index in the sorted order. And rank starts at 0.

Let’s create a sorted set of three members A, B, C with scores 40, 10 and 40.

` redis.zadd 'myset', 40, 'A'`

redis.zadd 'myset', 10, 'B'

redis.zadd 'myset', 40, 'C'

And when you do `redis.zrange 'myset', 0, -1`

, you get `["B", "A", "C"]`

and you can see that B is ranked first (rank 0), followed by A (rank 1) and then C (rank 2). This can also be verified by calling zrank on each item.

` redis.zrank 'myset', 'A'`

=> 1

redis.zrank 'myset', 'B'

=> 0

redis.zrank 'myset', 'C'

=> 2

My use case required the same rank for same scores and this is how I made Redis do what I wanted:

- I created a sorted set with the scores being the members themselves.

`redis.zadd 'newset', 10, 10`

redis.zadd 'newset', 40, 40

- Then I saved the member-score mapping in a hash separately.

`redis.hset 'myhash', 'A', 40`

redis.hset 'myhash', 'B', 10

redis.hset 'myhash', 'C', 40

- Now, when I need the rank of a member, I just need to look up the member’s score in the hash and find the rank of that score from the new sorted set.

`r = redis.hget 'myhash', 'A'`

=> "40"

redis.zrank 'newset', r

=> 1

r = redis.hget 'myhash', 'B'

=> "10"

redis.zrank 'newset', r

=> 0

r = redis.hget 'myhash', 'C'

=> "40"

redis.zrank 'newset', r

=> 1

That is, rank(A) and rank(C) are equal to rank(40) and rank(B) is equal to rank(10). This gives rank 1 for A and C and rank 0 for B which is exactly what I wanted. Yay!

Vaidik Kapoor

said:Interesting! I have used this kind of approach (i.e. using hashes) a couple of times myself.

lemig

said:Hi. you can do easily like this:

a_score = $r.zscore(‘myset’, ‘A’)

a_rank = $r.zcount(‘myset’, ‘-inf’, “(#{a_score}”)

=> 1

# 0 for b

# 1 for c

Cheers.

Miguel

Liu Kun (@lk_vc)

said:Great!

puneet

said:thats a really bad approach. How exactly do you update scores? what if ‘B’ moves to 20 you should remove 10 and add 20 to the set, now what if ‘A’ moes to 50?