Как реализовать интернет-рекорды в Google App Engine

Я хочу реализовать интернет-рекорды для своей игры. И дайте отзывы игрокам, которые у них есть (не только top100, либо что-то в этом роде). В обычном SQL это будет выглядеть так:

SELECT COUNT (*) FROM Scores WHERE points > : newUsersPoints

и GQL имеют нечто подобное

db.GqlQuery( "SELECT * FROM Score WHERE points > : 1", newUsersPoints).count()

но поскольку count() ограничен только 1000, это не будет очень полезно в моем случае. У вас есть идеи о том, как это реализовать?

У меня есть два

Во-первых:

  • Используйте идею счётчиков (http://code.google.com/intl/pl/appengine/articles/sharding_counters.html) Создайте новую "таблицу", в которой хранится количество баллов в некотором диапазоне (from_points, to_points)

  • Суммируйте все счетчики из таблицы выше, где range.to_points < newUsersPoints

  • Найдите, сколько очков больше, чем баллы в диапазоне, где новый счет db.GqlQuery( "SELECT * FROM Score WHERE points > : 1 AND points > =: 2 AND points <: 3", newUsersPoints, range.from_points, range.to_points).count() + sumfrom2

  • Найдите диапазон, в котором находится новый балл, и увеличивайте его счетчик

  • Диапазоны разделения, для которых счетчик больше 1000 (или 999), так что 3. не достигнет предела

  • Добавить новый счет в таблицу баллов

Это довольно сложно и подвержено ошибкам. Мы можем увеличить диапазон и время ожидания до добавления оценки. (не транзакционный)

Вторая идея:

Время от времени (один раз в день?) сортировать все баллы по точкам и давать им новые позиции (script может Timeout, поэтому мы должны делать это в кусках)

Чтобы узнать, в каком месте новый счет, мы просто делаем

db.GqlQuery( "SELECT * FROM Score WHERE points > : 1 LIMIT 1", newUsersPoints).get(). precalculated_position + 1

Любые другие идеи?

Ответ 1

Я использовал Ranker в нескольких приложениях GAE. Это приложения Facebook, в которых тысячи и сотни тысяч людей играют. Он работает хорошо, но для моих целей у него есть один большой недостаток: вам нужно заранее объявить окончательный диапазон, по которому будут падать баллы участника. Так что это плохо по двум причинам:

  • Если у вас есть конкурс без конца, где люди могут продолжать подниматься без верхнего предела, вы обручены.

  • в начале конкурса, когда все сгруппированы вместе около нуля, древовидная структура, используемая ranker.py, неэффективна. дерево идет очень глубоко и почти не использует его ширину.

Другими словами, ranker.py отлично подходит для случая, когда у вас есть конкурсанты, чьи оценки случайным образом распределяются равномерно по известному диапазону значений. Для других целей он менее оптимален.

Я надеюсь в ближайшее время разработать более полезный ранжирующий механизм. Если это произойдет, обязательно обновите этот поток!

Ответ 2

Этот поток в группе google-appengine, вероятно, будет интересен. Он также выглядит как библиотека, ranklist, специально для этого.

В принципе, похоже, что они делали что-то похожее на заштрихованные счетчики.