2

redis でソート済みセットを使用してリーダーボードを実装しました。同じスコアを持つユーザーを時系列で並べたい、つまり、最初に来たユーザーを上位にランク付けする必要があります。現在、redis は辞書順をサポートしています。それをオーバーライドする方法はありますか。モバイル番号は、ソート済みセットのメンバーとして使用されています。

私が考えた解決策の 1 つは、携帯電話番号の前にタイムスタンプを追加し、ハッシュを維持して携帯電話番号とタイムスタンプをマッピングすることです。

$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**01234567890    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 コードで並べ替えることができます。しかし、それは良い方法ではないようです。

それを行うためのより良いアプローチがあるかどうか知りたいです。または、私が意図したソリューションで行うことができる改善。

よろしくお願いします。

PSスコアは 50 の倍数です

4

3 に答える 3

3

ソートされたセットのスコアは倍精度浮動小数点数をサポートしているため、おそらくより良い解決策は、redis スコアを highscore.timestamp として保存することです。

例 (疑似コード)

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

これは、同じハイスコアを達成した複数のプレイヤーも、次のようにそのハイスコアを達成した時間に基づいてソートされることを意味します。

プレーヤー 1 の場合...

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

プレーヤー 2 の場合...

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

詳細については、この質問を参照してください: redis リーダーボードの一意のスコアリング

于 2013-03-03T20:20:15.187 に答える
0

sort コマンドの外部重み付け機能は、ここでの救世主です。


SORT mylist BY weight_*

http://redis.io/commands/sort

于 2012-10-19T06:32:32.653 に答える