# Создание простых таблиц

Простые таблицы — это таблицы, которые создаются однократно путём получения данных при создании из одного или нескольких источников. Простая таблица является неизменяемой, так как документы не могут быть добавлены или удалены в течение её времени жизни. Можно только обновлять значения числовых атрибутов (включая MVA). Обновление данных возможно только путём воссоздания всей таблицы.

Простые таблицы доступны только в [Plain режиме](../../Creating_a_table/Local_tables.md#Defining-table-schema-in-config-%28Plain mode%29), а их определение состоит из объявления таблицы и одного или нескольких объявлений источников. Сбор данных и создание таблицы выполняется не сервером `searchd`, а вспомогательным инструментом `indexer`.

**Indexer** — это инструмент командной строки, который можно запускать напрямую из командной строки или из shell-скриптов.

При вызове он может принимать ряд аргументов, но также есть несколько собственных настроек в конфигурационном файле Manticore.

В типичном сценарии indexer выполняет следующие действия:
* Извлекает данные из источника
* Строит простую таблицу
* Записывает файлы таблицы
* (Опционально) Информирует поисковый сервер о новой таблице, что вызывает ротацию таблиц

## Инструмент Indexer
Инструмент `indexer` используется для создания простых таблиц в Manticore Search. Его общий синтаксис:

```shell
indexer [OPTIONS] [table_name1 [table_name2 [...]]]
```

При создании таблиц с `indexer` сгенерированные файлы таблиц должны иметь права, позволяющие `searchd` читать, записывать и удалять их. В официальных пакетах для Linux `searchd` запускается от имени пользователя `manticore`. Поэтому `indexer` также должен выполняться от имени пользователя `manticore`:

```shell
sudo -u manticore indexer ...
```

Если вы запускаете `searchd` иначе, возможно, потребуется опустить `sudo -u manticore`. Просто убедитесь, что пользователь, под которым работает ваш экземпляр `searchd`, имеет права на чтение/запись к таблицам, созданным с помощью `indexer`.

Для создания простой таблицы нужно перечислить таблицу (или таблицы), которые вы хотите обработать. Например, если в вашем файле `manticore.conf` указаны две таблицы, `mybigindex` и `mysmallindex`, можно выполнить:

```shell
sudo -u manticore indexer mysmallindex mybigindex
```

Также можно использовать подстановочные токены для сопоставления имён таблиц:

* `?` соответствует одному любому символу
* `*` соответствует любому количеству любых символов
* `%` соответствует отсутствию или одному любому символу

```shell
sudo -u manticore indexer indexpart*main --rotate
```

Коды выхода indexer следующие:

* 0: всё прошло успешно
* 1: возникла проблема при индексации (и если указан `--rotate`, он был пропущен) или операция выдала предупреждение
* 2: индексация прошла успешно, но попытка `--rotate` не удалась

### Сервис systemd для Indexer

Вы также можете запускать `indexer` с помощью следующего unit-файла systemctl:

```shell
systemctl start --no-block manticore-indexer
```

Или, если хотите собрать конкретную таблицу:

```shell
systemctl start --no-block manticore-indexer@specific-table-name
```

Используйте команду `systemctl set-environment INDEXER_CONFIG`, чтобы запускать Indexer с пользовательской конфигурацией, заменяющей настройки по умолчанию.

Команда `systemctl set-environment INDEXER_ARGS` позволяет добавить собственные опции запуска для Indexer. Полный список опций командной строки смотрите [здесь](../../Data_creation_and_modification/Adding_data_from_external_storages/Plain_tables_creation.md#Indexer-command-line-arguments).

Например, чтобы запустить Indexer в тихом режиме, выполните:
```bash
systemctl set-environment INDEXER_ARGS='--quiet'
systemctl restart manticore-indexer
```

Чтобы отменить изменения, выполните:
```bash
systemctl set-environment INDEXER_ARGS=''
systemctl restart manticore-indexer
```

### Аргументы командной строки Indexer
* `--config <file>` (`-c <file>` как сокращение) указывает `indexer` использовать указанный файл в качестве конфигурации. Обычно он ищет `manticore.conf` в каталоге установки (например, `/etc/manticoresearch/manticore.conf`), затем в текущем каталоге, в котором вызывается `indexer` из shell. Это особенно полезно в общих средах, где бинарные файлы установлены в глобальную папку, например `/usr/bin/`, но вы хотите предоставить пользователям возможность создавать свои собственные настройки Manticore, либо если хотите запустить несколько экземпляров на одном сервере. В таких случаях вы можете разрешить им создавать собственные файлы `manticore.conf` и передавать их `indexer` с помощью этой опции. Например:

  ```shell
  sudo -u manticore indexer --config /home/myuser/manticore.conf mytable
  ```

* `--all` указывает `indexer` обновлять все таблицы, перечисленные в `manticore.conf`, вместо перечисления отдельных таблиц. Это полезно в небольших конфигурациях или для cron-задач или задач обслуживания, где весь набор таблиц пересоздаётся каждый день, неделю или любой другой удобный период. Обратите внимание, что так как `--all` пытается обновить все найденные таблицы в конфигурации, он выдаст предупреждение, если встретит RealTime таблицы, и код выхода команды будет `1`, а не `0`, даже если простые таблицы завершились успешно. Пример использования:

  ```shell
  sudo -u manticore indexer --config /home/myuser/manticore.conf --all
  ```

* `--rotate` используется для ротации таблиц. Если у вас нет ситуации, в которой можно отключить функцию поиска без неудобств для пользователей, вам почти наверняка нужно держать поиск запущенным во время индексации новых документов. `--rotate` создаёт вторую таблицу, параллельную первой (в том же месте, просто с включением `.new` в имена файлов). После завершения `indexer` уведомляет `searchd` с помощью сигнала `SIGHUP`, и `searchd` попробует переименовать таблицы (переименовать существующие, добавляя `.old`, и переименовать `.new` в оригинальные имена), затем начнёт обслуживать из новых файлов. В зависимости от настройки [seamless_rotate](../../Server_settings/Searchd.md#seamless_rotate) может быть небольшая задержка перед возможностью искать в новых таблицах. Если одновременно ротируются несколько таблиц, связанных отношениями [killlist_target](../../Creating_a_table/Local_tables/Plain_and_real-time_table_settings.md#killlist_target), ротация начнётся с таблиц, не являющихся целями, и закончится таблицами в конце цепочки целей. Пример использования:

  ```shell
  sudo -u manticore indexer --rotate --all
  ```
* `--quiet` указывает `indexer` не выводить ничего, если нет ошибок. Обычно используется для cron-задач или других скриптов, где вывод не нужен, кроме случаев ошибок. Пример использования:

  ```shell
  sudo -u manticore indexer --rotate --all --quiet
  ```
* `--noprogress` не отображает детали прогресса по мере выполнения. Вместо этого окончательные сведения о статусе (например, количество проиндексированных документов, скорость индексирования и так далее) выводятся только после завершения индексирования. В случаях, когда скрипт не запускается в консоли (или 'tty'), этот режим включён по умолчанию. Пример использования:

  ```shell
  sudo -u manticore indexer --rotate --all --noprogress
  ```
* `--buildstops <outputfile.text> <N>` просматривает исходную таблицу так, как если бы она индексировала данные, и создаёт список терминов, которые индексируются. Другими словами, он формирует список всех поисковых терминов, которые становятся частью таблицы. Обратите внимание, что таблица не обновляется, данные просто обрабатываются так, как будто происходит индексирование, включая выполнение запросов, определённых с помощью [sql_query_pre](../../Data_creation_and_modification/Adding_data_from_external_storages/Fetching_from_databases/Execution_of_fetch_queries.md#sql_query_pre) или [sql_query_post](../../Data_creation_and_modification/Adding_data_from_external_storages/Fetching_from_databases/Execution_of_fetch_queries.md#sql_query_post). В `outputfile.txt` будет содержаться список слов, по одному в строке, отсортированный по частоте, начиная с самых частых, а `N` задаёт максимальное количество слов в списке. Если это число достаточно велико, чтобы охватить все слова в таблице, будет возвращено именно столько слов. Такой словарь может использоваться в клиентских приложениях для функций вроде "Вы имели в виду…", обычно в сочетании с `--buildfreqs`, указанным ниже. Пример:

  ```shell
  sudo -u manticore indexer mytable --buildstops word_freq.txt 1000
  ```

  Это создаст в текущем каталоге документ `word_freq.txt` с 1000 наиболее распространённых слов в 'mytable', упорядоченных по убыванию частоты. Обратите внимание, что файл будет относиться к последней проиндексированной таблице при указании нескольких таблиц или `--all` (то есть последней в списке конфигурационного файла).

* `--buildfreqs` работает вместе с `--buildstops` (игнорируется, если `--buildstops` не указан). Поскольку `--buildstops` предоставляет список слов, используемых в таблице, `--buildfreqs` добавляет количество их вхождений, что полезно для определения, следует ли считать определённые слова стоп-словами, если они слишком часто встречаются. Это также помогает в разработке функций "Вы имели в виду…", где нужно знать, насколько одно слово распространено относительно другого, похожего. Например:

  ```shell
  sudo -u manticore indexer mytable --buildstops word_freq.txt 1000 --buildfreqs
  ```

  Это создаст `word_freq.txt`, как указано выше, но после каждого слова будет число, показывающее количество его вхождений в рассматриваемой таблице.

* `--merge <dst-table> <src-table>` используется для физического объединения таблиц, например, в случае [схемы main+delta](../../Creating_a_table/Local_tables/Plain_table.md#Main+delta-scenario), где основная таблица редко меняется, а дельта-таблица часто пересоздаётся; `--merge` применяется для их объединения. Операция выполняется справа налево — содержимое `src-table` анализируется и физически объединяется с содержимым `dst-table`, результат остаётся в `dst-table`. В псевдокоде это можно выразить как: `dst-table += src-table` Пример:

  ```shell
  sudo -u manticore indexer --merge main delta --rotate
  ```

  В приведённом примере, где основная таблица — основная, редко изменяемая, а дельта — более часто изменяемая, приведённый вызов `indexer` используется для объединения содержимого дельты с основной таблицей и переключения таблиц.

* `--merge-dst-range <attr> <min> <max>` применяет фильтр диапазона при слиянии. Конкретно, поскольку слияние применяется к целевой таблице (в рамках `--merge`, игнорируется при отсутствии `--merge`), `indexer` будет фильтровать документы, попадающие в целевую таблицу, и только документы, удовлетворяющие фильтру, окажутся в итоговой таблице. Например, в таблице с атрибутом 'deleted', где 0 означает «не удалён». Такая таблица может быть объединена с:

  ```shell
  sudo -u manticore indexer --merge main delta --merge-dst-range deleted 0 0
  ```

  Документы, помеченные как удалённые (значение 1), будут исключены из вновь объединённой целевой таблицы. Данный параметр можно указывать несколько раз в командной строке для добавления последовательных фильтров для слияния, каждый из которых должен быть выполнен, чтобы документ стал частью итоговой таблицы.

* --`merge-killlists` (и его короткий псевдоним `--merge-klists`) изменяет способ обработки списков удалённых при слиянии таблиц. По умолчанию после слияния оба списка удалённых отбрасываются. Это поддерживает наиболее распространённый сценарий слияния main+delta. Однако с включённым этим параметром списки удалённых из обеих таблиц объединяются и сохраняются в целевой таблице. Обратите внимание, что список удалённых из исходной (дельта) таблицы всегда используется для подавления строк из целевой (главной) таблицы.
* `--keep-attrs` позволяет повторно использовать существующие атрибуты при переиндексации. При перестроении таблицы идентификатор каждого нового документа проверяется на наличие в "старой" таблице; если найден, его атрибуты переносятся в "новую" таблицу; если нет — используются атрибуты из новой таблицы. Если пользователь обновил атрибуты в таблице, но не обновил источник данных, все изменения будут потеряны при переиндексации; использование `--keep-attrs` позволяет сохранить обновлённые значения атрибутов из предыдущей таблицы. Можно указать путь к файлам таблицы, который будет использован вместо пути из конфигурации:

  ```shell
  sudo -u manticore indexer mytable --keep-attrs=/path/to/index/files
  ```

* `--keep-attrs-names=<attributes list>` позволяет указать атрибуты, которые нужно повторно использовать из существующей таблицы при переиндексации. По умолчанию все атрибуты из существующей таблицы переносятся в новую:

  ```shell
  sudo -u manticore indexer mytable --keep-attrs=/path/to/table/files --keep-attrs-names=update,state
  ```

* `--dump-rows <FILE>` сохраняет строки, полученные из SQL-источника(ов), в указанный файл в синтаксисе, совместимом с MySQL. Полученные дампы точно представляют данные, как они принимаются `indexer`, и могут помочь воспроизвести ошибки, возникающие во время индексации. Команда выполняет извлечение из источника и создаёт как файлы таблиц, так и файл дампа.
* `--print-rt <rt_index> <table>` выводит полученные данные из источника в виде INSERT-запросов для таблицы реального времени. Первые строки дампа будут содержать поля и атрибуты таблицы реального времени (как отражение полей и атрибутов обычной таблицы). Команда выполняет извлечение из источника и создаёт как файлы таблиц, так и дамп-вывод. Команду можно использовать как `sudo -u manticore indexer -c manticore.conf --print-rt indexrt indexplain > dump.sql`. Поддерживаются только источники на базе SQL. Массивы MVA не поддерживаются.
* `--sighup-each` полезен, когда вы перестраиваете много больших таблиц и хотите, чтобы каждая была сразу же загружена в `searchd`. С `--sighup-each` `indexer` отправляет сигнал SIGHUP в searchd после успешного завершения работы над каждой таблицей. (Поведение по умолчанию — отправить один SIGHUP после построения всех таблиц).
* `--nohup` полезен, когда вы хотите проверить вашу таблицу с помощью indextool перед фактической загрузкой. Если эта опция включена, indexer не будет отправлять SIGHUP. Файлы таблиц переименовываются в .tmp. Используйте indextool для переименования файлов таблиц в .new и их загрузки. Пример использования:

  ```shell
  sudo -u manticore indexer --rotate --nohup mytable
  sudo -u manticore indextool --rotate --check mytable
  ```

* `--print-queries` выводит SQL-запросы, которые `indexer` отправляет базе данных, вместе с событиями подключения и отключения SQL. Это полезно для диагностики и устранения проблем с SQL-источниками.
* `--help` (`-h` для краткости) выводит список всех параметров, которые можно вызвать в `indexer`.
* `-v` отображает версию `indexer`.

### Настройки конфигурации Indexer
Вы также можете настроить поведение indexer в конфигурационном файле Manticore в разделе `indexer`:

```ini
indexer {
...
}
```

#### lemmatizer_cache

```ini
lemmatizer_cache = 256M
```
Размер кэша лемматизатора. Необязательно, по умолчанию 256K.

Наша реализация [лемматизатора](../../Server_settings/Common.md#lemmatizer_base) использует сжатый формат словаря, позволяющий идти на компромисс между использованием памяти и скоростью. Он может выполнять лемматизацию непосредственно сжатых данных, используя больше CPU, но меньше RAM, либо разархивировать и предварительно кэшировать словарь частично или полностью, используя меньше CPU, но больше RAM. Директива lemmatizer_cache позволяет контролировать, сколько точно оперативной памяти может быть выделено под этот несжатый кэш словаря.

В настоящее время доступны только словари [ru.pak, en.pak и de.pak](https://manticoresearch.com/install/). Это русские, английские и немецкие словари. Размер сжатого словаря примерно от 2 до 10 МБ. Обратите внимание, что словарь всё время хранится в памяти. Размер кэша по умолчанию — 256 КБ. Принимаемые размеры кэша — от 0 до 2047 МБ. Безопасно устанавливать размер кэша довольно большим; лемматизатор использует только необходимую память. Например, полный русский словарь разархивируется до примерно 110 МБ; установка `lemmatizer_cache` выше этого значения не увеличит использование памяти. Даже при разрешённом размере кэша 1024 МБ, если требуется только 110 МБ, будет использовано именно столько.

#### max_file_field_buffer

```ini
max_file_field_buffer = 128M
```

Максимальный адаптивный размер буфера для файловых полей в байтах. Необязательно, по умолчанию 8MB, минимум 1MB.

Буфер файлового поля используется для загрузки файлов, упомянутых в столбцах [sql_file_field](../../Data_creation_and_modification/Adding_data_from_external_storages/Fetching_from_databases/Processing_fetched_data.md#sql_file_field). Этот буфер адаптивный, начиная с 1 МБ при первом выделении и увеличивается в 2 раза до тех пор, пока либо содержимое файла не загрузится, либо не достигнет максимального размера буфера, указанного в директиве `max_file_field_buffer`.

Таким образом, если файловые поля не заданы, буфер не выделяется вообще. Если все файлы, загружаемые во время индексации, меньше (например) 2 МБ, но значение `max_file_field_buffer` равно 128 МБ, пиковое использование буфера всё равно будет только 2 МБ. Однако файлы больше 128 МБ будут полностью пропущены.

#### max_iops

```ini
max_iops = 40
```

Максимальное число операций ввода/вывода в секунду для ограничения скорости I/O. Необязательно, по умолчанию 0 (без ограничений).

Опция для ограничения скорости I/O. Ограничивает максимальное количество операций ввода/вывода (чтение или запись) за одну секунду. Значение 0 означает, что ограничений нет.

`indexer` может создавать всплески интенсивного дискового I/O во время построения таблицы, и может быть желательно ограничить его дискoвую активность (оставив ресурсы для других программ, например `searchd`). Ограничение скорости I/O помогает в этом. Оно обеспечивает минимальную задержку между последовательными операциями дискового ввода/вывода, выполняемыми `indexer`. Ограничение I/O может помочь уменьшить деградацию производительности поиска из-за построения. Эта настройка не влияет на другие виды внесения данных, например вставку данных в таблицу реального времени.

#### max_iosize

```ini
max_iosize = 1048576
```

Максимальный разрешённый размер операции ввода/вывода в байтах для ограничения скорости I/O. Необязательно, по умолчанию 0 (без ограничений).

Опция, связанная с ограничением скорости I/O. Ограничивает максимальный размер файловой операции ввода/вывода (чтения или записи) для всех операций, выполняемых `indexer`. Значение 0 означает отсутствие ограничений. Операции чтения или записи, превышающие лимит, будут разбиты на несколько меньших операций и посчитаны как несколько операций согласно настройке [max_iops](../../Data_creation_and_modification/Adding_data_from_external_storages/Plain_tables_creation.md#max_iops). На момент написания все операции ввода/вывода должны быть меньше 256 КБ (размер внутреннего буфера по умолчанию), поэтому значения max_iosize выше 256 КБ не должны иметь эффекта.

#### max_xmlpipe2_field

```ini
max_xmlpipe2_field = 8M
```

Максимально допустимый размер поля для источника типа XMLpipe2 в байтах. Необязательно, по умолчанию 2 МБ.

#### mem_limit

```ini
mem_limit = 256M
# mem_limit = 262144K # same, but in KB
# mem_limit = 268435456 # same, but in bytes
```

Ограничение использования оперативной памяти при построении простых таблиц. Необязательный параметр, по умолчанию 128 МБ. Принудительный лимит использования памяти, выше которого `indexer` не поднимется. Можно указать в байтах, килобайтах (с использованием постфикса K) или мегабайтах (с использованием постфикса M); см. пример. Этот лимит будет автоматически повышен, если установлено чрезвычайно низкое значение, приводящее к тому, что буферы ввода-вывода становятся меньше 8 КБ; точная нижняя граница для этого зависит от размера построенных данных. Если буферы меньше 256 КБ, будет выдано предупреждение.

Максимально возможный лимит — 2047M. Слишком низкие значения могут снизить скорость построения простых таблиц, но 256M–1024M должно быть достаточно для большинства, если не для всех наборов данных. Установка слишком высокого значения может вызвать таймауты SQL-сервера. Во время фазы сбора документов будут периоды, когда буфер памяти частично сортируется и связь с базой данных не выполняется; и сервер базы данных может превысить время ожидания. Это можно решить либо увеличением таймаутов на стороне SQL-сервера, либо уменьшением `mem_limit`.

#### on_file_field_error

```ini
on_file_field_error = skip_document
```

Как обрабатывать ошибки ввода-вывода в файловых полях. Необязательный параметр, по умолчанию `ignore_field`.
При возникновении проблемы с индексацией файла, на который ссылается файловое поле ([sql_file_field](../../Data_creation_and_modification/Adding_data_from_external_storages/Fetching_from_databases/Processing_fetched_data.md#sql_file_field)), `indexer` может либо обработать документ, предполагая пустое содержимое в этом конкретном поле, либо пропустить документ, либо полностью завершить индексацию с ошибкой. Директива `on_file_field_error` управляет этим поведением. Принимаемые значения:
* `ignore_field`, обработать текущий документ без поля;
* `skip_document`, пропустить текущий документ, но продолжить индексацию;
* `fail_index`, завершить индексацию с сообщением об ошибке.

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

Обратите внимание, что при `on_file_field_error = skip_document` документы будут игнорироваться только в том случае, если проблемы обнаружены на ранней фазе проверки, и **не** во время фактической фазы разбора файла. `indexer` откроет каждый указанный файл и проверит его размер перед началом работы, а затем откроет его снова при выполнении фактической работы по разбору. Поэтому, если файл исчезнет между этими двумя попытками открытия, документ все равно будет проиндексирован.

#### write_buffer

```ini
write_buffer = 4M
```

Размер буфера записи, байты. Необязательный параметр, по умолчанию 1 МБ. Буферы записи используются для записи как временных, так и окончательных файлов таблиц при индексации. Более крупные буферы уменьшают количество необходимых операций записи на диск. Память для буферов выделяется дополнительно к [mem_limit](../../Data_creation_and_modification/Adding_data_from_external_storages/Plain_tables_creation.md#mem_limit). Обратите внимание, что будет выделено несколько (в настоящее время до 4) буферов для разных файлов, что пропорционально увеличит использование оперативной памяти.

#### ignore_non_plain

```ini
ignore_non_plain = 1
```

`ignore_non_plain` позволяет полностью игнорировать предупреждения о пропуске непростых таблиц. По умолчанию 0 (не игнорировать).
<!-- proofread -->


### Планирование запусков indexer через systemd

Существует два подхода к планированию запусков indexer. Первый способ — классический метод использования crontab. Второй способ — использование таймера systemd с пользовательским расписанием. Чтобы создать файлы юнитов таймера, их следует поместить в соответствующий каталог, где systemd ищет такие файлы юнитов. В большинстве дистрибутивов Linux этот каталог обычно `/etc/systemd/system`. Вот как это сделать:

1. Создайте файл юнита таймера для вашего пользовательского расписания:
   ```shell
   cat << EOF > /etc/systemd/system/manticore-indexer@.timer
   [Unit]
   Description=Run Manticore Search's indexer on schedule
   [Timer]
   OnCalendar=minutely
   RandomizedDelaySec=5m
   Unit=manticore-indexer@%i.service
   [Install]
   WantedBy=timers.target
   EOF
   ```
   Подробнее о синтаксисе `OnCalendar` и примерах можно узнать [здесь](https://www.freedesktop.org/software/systemd/man/latest/systemd.time.html#Calendar%20Events).

2. Отредактируйте юнит таймера в соответствии с вашими потребностями.
3. Включите таймер:
   ```shell
   systemctl enable manticore-indexer@idx1.timer
   ```
4. Запустите таймер:
   ```shell
   systemctl start manticore-indexer@idx1.timer
   ```
5. Повторите шаги 2–4 для любых дополнительных таймеров.

