Closed jgadbois closed 12 years ago
Not currently. There would be a range of ranks that a given score could refer to as members in the leaderboard can have the same score.
That would be fine for my purposes. I don't see how to do that in Redis, though, without manually iterating through the results in the sorted sets. This would be a very useful feature for me, because on some pages I want to show how a user's score stacks up in terms of the leaderboard. Happy to help implement if you have any good ideas on how to do so.
In theory I suppose to be guaranteed a unique answer, the question could be posed not as "what rank would a score of 12345 give me" but "how many items in the leaderboard currently rank ahead of the score 12345" (the answer could be 0 if that's higher than anything currently in the leaderboard).
@jletourneau yes, I am actually doing that now in my current Postgres implementation.
rank = number of scores that are greater than my score + 1
@jgadbois Would the percentile_for(member)
method work for you here?
@czarneckid no, because I'm talking about a non-high score for a user (so it won't actually be in the sorted set)
sorry accidentally closed
You could look at zrangebyscore or zrevrangebyscore to get the members at a score and then grab the ranks for those members or maybe just the first member.
Not sure if this would do what you want, but check out the leaders-from-score-range branch. In particular, https://github.com/agoragames/leaderboard/commit/858af9ac599543245cd6ec9dec2a33fd6d79157d.
leaders = highscore_lb.leaders_from_score_range(4, 19)
=> [{:member=>"member_10", :rank=>47, :score=>10.0}, {:member=>"member_9", :rank=>48, :score=>9.0}, {:member=>"member_8", :rank=>49, :score=>8.0}, {:member=>"member_7", :rank=>50, :score=>7.0}, {:member=>"member_6", :rank=>51, :score=>6.0}, {:member=>"member_5", :rank=>52, :score=>5.0}, {:member=>"member_4", :rank=>53, :score=>4.0}]
That would definitely get me close. Say particular score I was looking at was 17. I could grab leaders for some range of scores around that (say 7-27), manually filter down to see who was closest to 17, and grab their rank.
There would be an issue if no members were found within a certain range because I would have no ranks to compare against.
The only other seemingly applicable method here is total_members_in_score_range
which uses the Redis sorted set command zcount to get the total # of elements within a score range. I guess you could have custom logic which centered around a given score, opened up the range slightly until finding some # of members > 0 and then grabbing the members from the given score range.
Yeah that's kind of what I was thinking. I think if you added these functions, then I could do what I wanted to by writing the custom logic you describe.
Well, total_members_in_score_range
is already available. I'll merge the leaders-from-score-range branch in next week. I want to make sure I've noodled on that for a bit.
Ok, thanks!
Would you be interested in having this algorithm inside of the leaderboard gem vs in my app logic?
I think a good compromise here would be a wiki page demonstrating that particular use-case. I believe you should be able to edit the main page in the wiki and go over the use-case and your code in a sub-page.
Is there a way that I could pass leaderboard a number and get back the rank that score would be at?