Тема: Алгоритм отримання даних для лідерборду

Добридень. В мене є база з акаунтами користувачів, ця база не якась там mysql, а зовсім інше. У кожного користувача є різні поля, серед них є поле score і поле country. Як ви вже зрозуміли, перше поле це прогрес користувача в грі, чи більше це поле, тим він вище в лідерборді знаходиться, ну а друге поле - код країни.
Я вам поясню за першу задачу, і як я її зробив, аби було зрозуміле питання.
Нехай деякий користувач має score=300, а всього користувачів у нас 1000. Нам потрібно взяти 40 користувачів, у котрих score менше, і 40, у котрих більше. Тобто наш користувач має бути посередині цього списку. При цьому у кожного отриманого запису має бути порядковий номер відносно всього списку з користувачами.
Ось псевдокод, що робить це все
Спершу отримаємо позицію користувача серед усіх користувачів

var userRank = query.orderByDescending("score").lessOrEqual("score", myScore).Count();

а тепер візьмемо 80, або менше юзерів, що знаходяться з обох сторін користувача.

var users = query.OrderByDescending("score").Skip(userRank-40).Limit(80);

Тут ми спочатку сортуємо список по полю score в порядку спадання, тобто юзер з найбільшим score буде першим. Далі ми пропускаємо таку кулькість користувачів, після котрої до запису обраного юзера буде залишатись ще 40 юзерів, і після цього ми беремо перших 80 юзерів за допомогою лімітації.
Тепер у нас є 80 юзерів, і очевидно, що найперший з них буде мати позицію (rank) котра дорівнює userRank-40. Ми проходимось по всім 80 юзерам і присвоюємо кожному свій rank

int i = userRank-40;
foreach(var user in users)
{
user.Rank=i;
i++;
}

Гаразд. З цією задачею все зрозуміло.
А тепер увага, питання!
Як нам дістати 90 юзерів, у котрих поле country дорівнює ua, при цьому нумерація (ranking) повинна бути відносно всього списку з користувачами?
Ось вам приклад з 10 користувачами.

1 2(ua) 3(ua) 4 5(ua) 6 7(ua) 8 9(ua) 10
Тобто є 10 користувачів, і нам потрібно знайти 8 користувачів з центром в 5.
Тут не буде восьми користувачів з полем country=ua, тому результат має бути таким

2,3,5,7,9 і ось ци цифри - це нумерація користувачів відносно всього списку.
Якщо я б зробив от такий запит

var users = query.OrderByDescending("score").WhereEqualTo("country","ua").Skip(userRank-40).Limit(80);

То я б отримав користувачів з полем country=ua, але якби я їх далі пронумерував, то нумерація була б невірна. Різниця в rank між сусідніми користувачами дорівнювала б одиниці, хоча в реальному списку між ними може бути надцять користувачів без поля country, що дорівнює ua.

Так як мені ото зробити? Наразі є лишень одна думка - спершу нумерувати усіх-преусіх користувачів, тобто надати кожному свій rank, незалежно від поля country. Але проблма в тому, що користувачі може бути дуууже багато, а цей запит буде виконуватись кожного разу, коли якийсь з користувачів захоче подивитись, яке він має місце в лідерборді.

Подякували: 0xDADA11C71

2

Re: Алгоритм отримання даних для лідерборду

багатобукаф!
здається запит на зразок SELECT...LIMIT 40 дає не 40 рядків, а не більше 40.
У чому проблема перевірити кількість рядків відповіді і зробити відповідні висновки?

3

Re: Алгоритм отримання даних для лідерборду

DNS написав:

багатобукаф!
здається запит на зразок SELECT...LIMIT 40 дає не 40 рядків, а не більше 40.
У чому проблема перевірити кількість рядків відповіді і зробити відповідні висновки?

Ну да, не більше. І це нормально, якщо записів менше потрібної кількості.
То ви мені пропонуєте робити так:
- беремо центер, нехай знову це буде 300
- просимо дати нам користувачів від 260 до 340, в котрих поле country=="ua"
- воно нам повертає один запис
І що тепер? просити дати нам користувачів від 160 до 440, А а якщо воно дасть нам 200 користувачів, а потрібно лише 40, і, бажано, аби перші 40 були до центру, тобто до 300, а решта після трьохсотого користувача? А як нам їх потім нумерувати? Тупо від 1 до 200? так не піде, потрібна нумерація відносно усього списку

4

Re: Алгоритм отримання даних для лідерборду

Так а якщо 90 немає узагалі?
Будемо циклювати до нескінченності?

LIMIT 40 дасть 40 записів, якщо вони є. Якщо ні - то їх НЕМАЄ

5

Re: Алгоритм отримання даних для лідерборду

Якщо ж Ви винаходите велосіпєд і хочете створити власну СУБД, то скажіть

6

Re: Алгоритм отримання даних для лідерборду

DNS написав:

Якщо ж Ви винаходите велосіпєд і хочете створити власну СУБД, то скажіть

Прихований текст

Не пишіть мені більше нічого. Просто вийдіть з теми, аби я не читав вашого безглуздя.

7

Re: Алгоритм отримання даних для лідерборду

Як нам дістати 90 юзерів, у котрих поле country дорівнює ua, при цьому нумерація (ranking) повинна бути відносно всього списку з користувачами?

Робити 2 запита?

8

Re: Алгоритм отримання даних для лідерборду

Invader написав:

Як нам дістати 90 юзерів, у котрих поле country дорівнює ua, при цьому нумерація (ranking) повинна бути відносно всього списку з користувачами?

Робити 2 запита?

Ну ви хоча б пояснили ширше, які саме два запита.

9

Re: Алгоритм отримання даних для лідерборду

Ну в мене така ідея: першим запитом вибирати всі записи де country дорівнює ua а потім брати ідентифікатори (чи якісь інші дані які однозначно вказують на користувача) цих користувачів і вибирати їхні порядкові номери.

І що за нумерація така? Що за БД? Mongo?

10

Re: Алгоритм отримання даних для лідерборду

Invader написав:

Ну в мене така ідея: першим запитом вибирати всі записи де country дорівнює ua а потім брати ідентифікатори (чи якісь інші дані які однозначно вказують на користувача) цих користувачів і вибирати їхні порядкові номери.

І що за нумерація така? Що за БД? Mongo?

ну так, в мене така сама була ідея, я юзаю Parse, а шо вони там юзають - я хз

11

Re: Алгоритм отримання даних для лідерборду

Що таке Parse?

12

Re: Алгоритм отримання даних для лідерборду

Invader написав:

Що таке Parse?

то такий сервіс https://www.parse.com/