Перейти к содержимому

Индексы сервера

Индексы сервера — особое хранилище данных, предназначенное для хранения большого массива отсортированных данных. Данный тип хранилища применим для создания рейтингов (топов) чего-либо, историй заметок участников или любых других сортируемых записей.

Это хранилище состоит из двух частей: Индексы и Записи.

Под индексом понимается группа записей. На сервере может быть неограниченное количество таких индексов (групп) с уникальными названиями, каждая из которых содержит в себе неограниченное количество записей с уникальными ключами и соответствующими им числовыми значениями.

Индексы представлены методом getIndex и свойством indexes у типа Guild.

Внимание

В рамках выполнения одного шаблона сообщения допускается обращение максимум к 2 разным индексам сервера и запрос/обновление до двух записей любого индекса.

Сохранение данных

Для сохранения каких-либо данных в индексы можно использовать следующие конструкции:

JuniperBot Template
{% do guild.getIndex('myIndex').get('entryKey').update(123) %}

Здесь используются:

  1. Метод getIndex у типа Guild для получения индекса с названием myIndex;
  2. Метод get у типа GuildIndex для получения записи этого индекса с ключом entryKey;
  3. Метод update у типа GuildIndexEntry для сохранения значения 123 в эту запись.

Также можно обновить сразу до двух записей в индексе одновременно, используя метод update у типа GuildIndex:

JuniperBot Template
{% do guild.getIndex('myIndex').update({ entryKey1: 123, entryKey2: 321 }) %}

Вы можете увеличить или уменьшить значение записи на указанное число, используя методы increment и decrement:

Увеличение значения:

JuniperBot Template
{% do guild.getIndex('myIndex').get('entryKey').increment(1) %}

Уменьшение значения:

JuniperBot Template
{% do guild.getIndex('myIndex').get('entryKey').decrement(1) %}

Запрос данных

Конкретное значение

Индексы и их записи хранятся бессрочно и доступ к ним можно получить следующими способами:

JuniperBot Template
{{ guild.getIndex('myIndex').get('entryKey').value }}

Страница

Самое интересное и то, ради чего индексы создавались — запрос страницы записей индекса, отсортированные по их значению. Для этого используется метод getPageOf:

JuniperBot Template
{% set page = guild.getIndex('myIndex').getPageOf(0, 10, 'DESC') %}

Таким образом вы получите объект страницы с типом Page, содержащий в себе список записей GuildIndexEntry, а также дополнительную информацию, позволяющую реализовать даже постраничную навигацию!

Пример постраничной навигации

Следующий код демонстрирует пример топа балансов с постраничной навигацией.

Вам необходимо создать действие отправки сообщения в режиме текста, поставить в нём галочку "Отредактировать сообщение компонента" и вставить следующий код, заменив UUID действия в первой строчке на свой.

JuniperBot Template
{% 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:

JuniperBot Template
{% do guild.getIndex('myIndex').get('entryKey').clear() %}

Здесь используются:

  1. Метод getIndex у типа Guild для получения индекса с названием myIndex;
  2. Метод get у типа GuildIndex для получения записи этого индекса с ключом entryKey;
  3. Метод clear у типа GuildIndexEntry для очистки записи.

Если вы хотите очистить вообще все записи конкретного индекса, используйте метод clearAll у типа GuildIndex:

JuniperBot Template
{% do guild.getIndex('myIndex').clearAll() %}

Все права зафырканы.