2012-10-13 34 views
2

我已經在redis中使用排序集實現了排行榜。我希望分數相同的用戶按照時間順序排列,即排在前面的用戶排名要高一些。目前redis支持字典順序。有沒有辦法來覆蓋它。移動號碼正被用作排序集中的成員。redis zrevrangebyscore,除排序順序以外的排序

我想到的一個解決方案是在移動號碼前添加時間戳,並維護一個哈希來映射手機號碼和時間戳。

$redis.hset('mobile_time', '1234567890', "#{Time.now.strftime('%y%m%d%H%M%S')}") 
pref = $redis.hget('mobile_time, '1234567890'') 
$redis.zadd('myleaderboard', "1234567890:#{pref}") 

這樣我就可以在任何實例中通過添加哈希前綴來獲得給定用戶的等級。

現在這不完全是我想要的。這將返回與我想要的相反。提前到達的用戶將被放置在晚點來的用戶之下(兩者的得分相同)。

Key for user1 = 201210121953**23**score: 400 
key for user2 = 201210121253**26**09313123523 score: 400 (3 seconds later) 

如果我使用zrevrangebyscore,user2將放置得比user1高。

然而,有一種方式來獲得期望的等級:

users_with_higher_score_count = $redis.zcount("mysset", "(400", "+inf") 
users_with_same_score = $redis.zrangebyscore("mysset", "400", "400") 

現在我有列表users_with_same_score用正確的順序。看指數我可以計算用戶的排名。

要獲得排行榜。我可以每隔50分鐘獲得成員,並通過ruby代碼進行排序。但它似乎並不是一個好方法。

我想知道是否有更好的方法來做到這一點。或者我可以在解決方案中進行任何改進。

在此先感謝您的幫助。

P.S. 得分都在50

回答

3

的有序集合的得分支持雙精度浮點數你的救星,所以可能更好的解決方案是將redis分數存儲爲高分。時間戳

例如(僞)

highscore = 100 
timestamp = now() 
redis.zadd('myleaderboard', highscore + '.' + timestamp, playerId) 

這意味着誰取得了同樣的高分多個玩家也將分類基礎上的時候,他們實現了高分按照以下

對於播放器1 ...

redis.zadd('myleaderboard', '100.1362345366', "Charles") 

對於玩家2 ...

redis.zadd('myleaderboard', '100.1362345399', "Babbage") 

更多細節見這個問題:Unique scoring for redis leaderboard

+0

謝謝。有趣的解 – goyalankit

+0

嗨哈利,你如何在這種情況下做incby如果得分不是一個分數,它是一個計數的數字?應該手動嗎? – Maziyar

+0

Maziyar我不完全理解你的問題,但我認爲你指的是它不再是'incrby'的整數?有'zincrby'命令與雙精度浮點數一起使用。 – 2013-10-23 09:00:17

0

sort命令的外部砝碼功能的倍數是這裏


SORT mylist BY weight_* 

http://redis.io/commands/sort

+0

有意思,我從來沒有在Redis的使用清單。我會檢查出來的。 – goyalankit