Индексы сервера
Индексы сервера — особое хранилище данных, предназначенное для хранения большого массива отсортированных данных. Данный тип хранилища применим для создания рейтингов (топов) чего-либо, историй заметок участников или любых других сортируемых записей.
Это хранилище состоит из двух частей: Индексы и Записи.
Под индексом понимается группа записей. На сервере может быть неограниченное количество таких индексов (групп) с уникальными названиями, каждая из которых содержит в себе неограниченное количество записей с уникальными ключами и соответствующими им числовыми значениями.
Индексы представлены методом getIndex и свойством indexes у типа Guild.
Внимание
В рамках выполнения одного шаблона сообщения допускается обращение максимум к 2 разным индексам сервера и запрос/обновление до двух записей любого индекса.
Сохранение данных
Для сохранения каких-либо данных в индексы можно использовать следующие конструкции:
{% do guild.getIndex('myIndex').get('entryKey').update(123) %}
Здесь используются:
- Метод
getIndexу типа Guild для получения индекса с названиемmyIndex; - Метод
getу типа GuildIndex для получения записи этого индекса с ключомentryKey; - Метод
updateу типа GuildIndexEntry для сохранения значения123в эту запись.
Также можно обновить сразу до двух записей в индексе одновременно, используя метод update у типа GuildIndex:
{% do guild.getIndex('myIndex').update({ entryKey1: 123, entryKey2: 321 }) %}
Вы можете увеличить или уменьшить значение записи на указанное число, используя методы increment и decrement:
Увеличение значения:
{% do guild.getIndex('myIndex').get('entryKey').increment(1) %}
Уменьшение значения:
{% do guild.getIndex('myIndex').get('entryKey').decrement(1) %}
Запрос данных
Конкретное значение
Индексы и их записи хранятся бессрочно и доступ к ним можно получить следующими способами:
{{ guild.getIndex('myIndex').get('entryKey').value }}
Страница
Самое интересное и то, ради чего индексы создавались — запрос страницы записей индекса, отсортированные по их значению. Для этого используется метод getPageOf:
{% set page = guild.getIndex('myIndex').getPageOf(0, 10, 'DESC') %}
Таким образом вы получите объект страницы с типом Page, содержащий в себе список записей GuildIndexEntry, а также дополнительную информацию, позволяющую реализовать даже постраничную навигацию!
Пример постраничной навигации
Следующий код демонстрирует пример топа балансов с постраничной навигацией.
Вам необходимо создать действие отправки сообщения в режиме текста, поставить в нём галочку "Отредактировать сообщение компонента" и вставить следующий код, заменив UUID действия в первой строчке на свой.
{% set actionId = 'ae04dfed-e19c-49d3-84fc-b05cec59976e' %}
{% set targetMember = arguments.targetMember %}
{% if targetMember and not component %}
{% set newBalance = random(1000) %}
{# Получаем запись баланса для участника из индекса балансов #}
{% set balanceEntry = guild.indexes.balances.get(targetMember.id) %}
{# Обновляем баланс на новый #}
{% do balanceEntry.update(newBalance) %}
Баланс {{ targetMember }} установлен на {{ newBalance }}!
{% else %}
{# Вычисляем номер запрашиваеой страницы #}
{% set wasLast = parameters.get('page.isLast') %}
{% set pageNum = (parameters.get('page.number')) ?: 0 %}
{% if component.id == 'next_page' and not wasLast %}
{% set pageNum += 1 %}
{% elseif component.id == 'prev_page' and pageNum > 0 %}
{% set pageNum -= 1 %}
{% endif %}
{# Получаем страницу из индекса, сохраняя в параметры данные для возможности вычисления номера новой страницы #}
{% set page = guild.indexes.balances.getPageOf(pageNum, 2, 'DESC') %}
{% do parameters.store('page.number', page.number) %}
{% do parameters.store('page.isLast', page.isLast) %}
{% set isEmpty = page.totalPages <= 0 %}
{% if not isEmpty -%}
{# Если в индексе есть данные, показываем содержимое страницы #}
Страница {{ page.number + 1 }} из {{ page.totalPages }} (всего {{ page.totalElements }} элементов)
{% for entry in page %}
{% set number = loop.index + page.number * page.size -%}
{{ number }}. <@{{ entry.key }}>: {{ entry.value -}}
{% endfor %}
{%- else -%}
Записи отсутствуют
{%- endif %}
{# Отобразим кнопки пагинации #}
{% set pageLabel = (page.number + 1) ~ ' / ' ~ page.totalPages %}
{% do button('PRIMARY', 'prev_page', null, '⬅️', actionId, isEmpty or page.isFirst) %}
{% do button('SECONDARY', 'current_page', pageLabel, null, actionId, true) %}
{% do button('PRIMARY', 'next_page', null, '➡️', actionId, isEmpty or page.isLast) %}
{% endif %}
При запуске команды с таким шаблоном отправляется сообщение с постраничной пагинацией балансов из индекса.
Изначально записей в индексе нет, но вы можете выполнить эту команду, упомянув в ней разных участников для установки им произвольных балансов, после чего запустить команду без упоминания и получить рабочую пагинацию.
Внимание
В рамках выполнения одного шаблона сообщения допускается запрос только одной страницы одного любого индекса, в которой может быть до 25 записей.
Очистка данных
Для очистки записи индекса следует использовать метод clear у типа GuildIndexEntry:
{% do guild.getIndex('myIndex').get('entryKey').clear() %}
Здесь используются:
- Метод
getIndexу типа Guild для получения индекса с названиемmyIndex; - Метод
getу типа GuildIndex для получения записи этого индекса с ключомentryKey; - Метод
clearу типа GuildIndexEntry для очистки записи.
Если вы хотите очистить вообще все записи конкретного индекса, используйте метод clearAll у типа GuildIndex:
{% do guild.getIndex('myIndex').clearAll() %}