user479947
user479947

Reputation:

Sorting a list with a hash table lookup

I have a list of groups with IDs stored in a hash table that I would like to sort using a matching hash table of votes. The data is in the format:

RPUSH group groupA
RPUSH group groupB
RPUSH group groupC

HSET g:1 group: groupA
HSET g:2 group: groupB
HSET g:3 group: groupC

HINCRBY groupVotes g:1 2
HINCRBY groupVotes g:2 3
HINCRBY groupVotes g:3 1

If I query red:lrange('group', 0, 2) I get back {'groupA', 'groupB', 'groupC'}

How can I sort this list by groupVotes descending to return {'groupB', 'groupA', 'groupC'}?

Upvotes: 0

Views: 149

Answers (1)

FGRibreau
FGRibreau

Reputation: 7229

If groupVotes was a zset you could use an algorithm like:

$keys = `zrevrange groupVotes 0 2`
$list = []
for($key in keys)
 $list.push(`hget $key group:')
$list

That way you don't need RPUSH. Even better, if the zset had directly the group names instead of the key name member the command zrange groupVotes 0 2 would be enough!

Nonetheless for the exercise I translated the above algorithm in LUA (still using groupVotes as a zset):

local a = {}
local keys = redis.call('zrevrange', KEYS[1], ARGV[1], ARGV[2]);
for i, name in ipairs(keys) do
  table.insert(a, redis.call('hget', name, 'group:'))
end
return a

Save it in test.lua and then run

$ redis-cli --eval test.lua groupVotes , 0 2
1) "groupB"
2) "groupA"
3) "groupC"

Now you just have to use it inside your code with the EVAL and EVALSHA (requires Redis 2.6+) commands.

Note: It's way better to use LUA here to remove network roundtrip due to the algorithm.

Upvotes: 0

Related Questions