私はGoogleAppEngineを使用しているので、非リレーショナルデータベース(NoSQL)を使用しています。私の質問は:
スコアを使用してランク(プレーヤーのランク付け)をモデル化するための最良のオプションはどれですか?
たとえば、私のプレーヤーは次のとおりです。
Player { String name, int score}
プレイヤーのランク(順位)を知り、上位10名を獲得したいのですが、どちらが一番いいのか疑問です。
ありがとう。
私はGoogleAppEngineを使用しているので、非リレーショナルデータベース(NoSQL)を使用しています。私の質問は:
スコアを使用してランク(プレーヤーのランク付け)をモデル化するための最良のオプションはどれですか?
たとえば、私のプレーヤーは次のとおりです。
Player { String name, int score}
プレイヤーのランク(順位)を知り、上位10名を獲得したいのですが、どちらが一番いいのか疑問です。
ありがとう。
スコアにインデックスが付けられている場合、データストアクエリを実行して、プレーヤーを並べ替えた順序で取得するのは簡単です。したがって、上位10人のプレーヤーが必要な場合、それは非常に簡単です。
任意のプレイヤーのランキングを取得するのは本当に難しいです。私が言うには十分に難しいですが、可能であればそれを避け、できない場合はそれを回避する方法を見つけてください。
たとえば、50,000人のプレーヤーがいて、PlayerXが12,345にランク付けされている場合、それを知る唯一の方法は、すべてのプレーヤーにクエリを実行し、PlayerXが見つかるまでカウントを続けながら各プレーヤーをチェックすることです。
1つのハックは、プレーヤーのランキングをプレーヤーエンティティに保存し、数時間に1回実行されるcronジョブで更新することです。
Redisには組み込みのソリューションがあります:
まず、スコアの付いたメンバーをいくつか追加します。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
「2」のランクを取得します。
redis> ZREVRANK myzset "one"
(integer) 2
(インデックスは0から始まります)
また、現在の注文が必要な場合:
redis> ZREVRANGE myzset 0 -1
1) "three"
2) "two"
3) "one"
redisドキュメントのZREVRANGEおよびZREVRANKを参照してください。
JSONでのこれの適切な表現は次のようになります。
"players" : [
{
"name" : "John",
"score" : 15
},
{
"name" : "Swadq",
"score" : 7
},
{
"name" : "Jane",
"score" : 22
}
]
これを並べ替える方法の例:
次のようにindex.yamlを設定できます。
- kind: Player
properties:
- name: score
direction: ascending
プレーヤーのスコアを取得するには、(カウントを維持しながら)プレーヤーをパスし、結果をキャッシュして、そのプレーヤーの検索をさらに高速化する必要があります。