blog-post

Индексы Manticore Search и хранение документов

Начиная с версии 3.2.0, Manticore Search представил новую функцию - Хранение Документов.

Исторически Manticore Search был текстовым поисковым движком, который индексирует тексты, но не сохраняет оригиналы. Текст обрабатывается, преобразуя его из обычной строки в специальные структуры, которые формируют полнотекстовый индекс, что позволяет быстро искать текст. В результате пользователь не получал оригинальный текст, так как его восстановление из полнотекстового индекса может быть сложным процессом. Кроме того, настройки индексации могут включать условия, которые останавливают индексацию определенных слов (например, минимальная длина слова или стоп-слова), что может сделать восстановление невозможным.

Рабочий процесс поиска был создан для выполнения полнотекстового поиска в Manticore и на основе набора результатов для выполнения дополнительного поиска в оригинальном источнике данных (либо в базе данных, либо в файлах), чтобы извлечь контент, который был только индексирован в Manticore. В некоторых случаях дополнительный поиск необходим для извлечения не только «пропущенных» текстов, но и других данных, не включенных в индекс, потому что они не используются в операциях поиска, и эти данные только увеличивали бы (необоснованно) размер индекса. Но есть много случаев, когда единственной целью поиска является получение «пропущенных» текстов, что рассматривается как дополнительный шаг, который было бы хорошо устранить - так как это означает упрощение кода приложения, избегание дополнительной нагрузки, потребления ресурсов и еще одной точки отказа от хранения данных.

Существуют также некоторые сценарии, когда оригинальные данные не находятся в традиционной базе данных, и извлечение оригинальных текстов из данных во время запроса может быть медленным. Требование хранения этих данных в базе данных может рассматриваться как нежелательное и как единственная причина использования базы данных для компенсации неспособности поискового движка хранить оригинальный контент. Эти сценарии могут быть:

  • компания может захотеть иметь возможность искать тексты в офисных документах, таких как Word или PDF - они могут быть частью внутренних инструментов или портала, предлагающего научные, юридические или технические статьи.
  • данные поступают из веб-сервиса или из проиндексированных страниц
  • потоковые данные, которые могут быть журналами, сообщениями или электронными письмами. Чтение их из источников может быть сложным, так как во многих случаях они хранятся в распределенных системах, и чтение их во время запроса усложняет код приложения

Вы можете пройти наш интерактивный курс , чтобы узнать, как использовать не только индексацию, но и хранить содержимое документов.

Теперь возможно хранить оригинальные тексты и извлекать их обратно в результатах.

Мы должны упомянуть, что функция DS не делает Manticore традиционной базой данных. Manticore поддерживает транзакции и восстановление из бинарного лога, и хотя он предлагает большинство свойств ACID, его не считают истинной базой данных, соответствующей ACID.

На данный момент также нет шифрования для хранения. Чувствительные или критические данные, такие как учетные данные пользователей или платежные транзакции, не рассматриваются как подходящие для хранения в Manticore. Также есть функции традиционных баз данных, такие как JOIN, которые еще не поддерживаются. Но мы будем работать над этим в будущих версиях.

Тем не менее, есть много случаев, когда использование Manticore только для хранения данных или хранения и не выполнения дополнительных поисков имеет большой смысл.

Хранение документов может снизить нагрузку на оригинальный хранилище данных или уменьшить требования к пространству.
Другим аспектом на момент написания этой статьи является производительность хранения документов. Но мы ожидаем значительно улучшить этот аспект в следующих релизах.

Использование

Хранение можно включить, используя директиву индекса stored_fields, которая принимает список имен полей, разделенных запятыми.

index myindex {
   type     = rt
   path     = /path/to/myindex
   rt_field  = title
   rt_field = short_description
   rt_field = long_description
   rt_attr_string = title
   rt_attr_uint   = group_id
   stored_fields  = short_description, long_description
}

Без сохраненных полей результат будет выглядеть так:

mysql> SELECT * FROM myindex WHERE ....\G
*************************** 1. row ***************************
      id: 11
   title: A title goes here
group_id:100
*************************** 2. row ***************************
...

С сохраненными полями:

mysql> SELECT * FROM myindex WHERE ....\G
*************************** 1. row ***************************
               id: 11
            title: A title goes here
short_description: A short text description
goes here
 long_description: A long text description
can be found here
         group_id:100
*************************** 2. row ***************************
...

Пример между индексом с и без хранения документов можно увидеть в нашем курсе по docstore .

Расширенная настройка

Тексты хранятся в отдельном файле на диске. По умолчанию они сжимаются с использованием алгоритма lz4. Альтернативный алгоритм lz4hc доступен, или сжатие можно отключить ('none'), установив директиву индекса 'docstore_compression'. Для алгоритма 'lz4hc' уровень сжатия можно настроить с помощью директивы индекса docstore_compression_level, которая может принимать значения от 1 до 12 (по умолчанию 9). Тексты сжимаются на диске блоками. Размер блока можно настроить с помощью директивы docstore_block_size. Значение по умолчанию - 16k. Увеличение размера блока улучшит коэффициент сжатия и сэкономит больше дискового пространства, в то время как уменьшение размера блока должно улучшить скорость доступа.

Когда поиск требует текст из хранилища, блок, содержащий его, считывается с диска и распаковывается. Поскольку возможно, что блок может содержать тексты из нескольких документов, распакованные блоки могут быть кэшированы в памяти. По умолчанию используется кэш размером 16 МБ на уровне демона. Размер кэша можно изменять с помощью настройки docstore_cache_size в searchd.

Отличия от строковых атрибутов

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

Строковые атрибуты хранятся в компоненте blob индекса Manticore Search 3, который также содержит JSON и MVA атрибуты. Чтение из компонента blob управляется с помощью mmap() и может оставаться на диске и читаться по мере необходимости, читаться и загружаться полностью при загрузке индекса или читаться, загружаться и блокироваться в памяти. Тексты в строковых атрибутах хранятся в несжатом виде. Если тексты, хранящиеся таким образом, длинные (например, описания, содержимое статей), они могут занять много места на диске и также увеличат объем памяти, используемой компонентом blob документа. Для индекса, который ранее не помещался полностью в ОЗУ, добавление длинных текстов в качестве строковых атрибутов означает меньше атрибутов переменной длины (строковых, JSON, MVA), которые могут быть кэшированы в ОЗУ, что приведет к менее желаемой производительности. Блокировка в памяти компонента blob (access_blob_attrs=mlock) может быть невозможна из-за увеличенного размера. Строковые атрибуты следует использовать для коротких текстов, по которым ожидается выполнение операций фильтрации, группировки и сортировки, кроме простого извлечения.

С другой стороны, хранимые поля являются отдельным компонентом. Тексты читаются только с диска, и если ОЗУ доступна, docstore_cache_size может быть установлен на большие значения (ГБ), чтобы кэшировать хранимые поля в ОЗУ. Кроме того, хранимые поля по умолчанию сжаты, занимая меньше места на носителе, чем строковые атрибуты. Также есть случаи, когда тексты необходимо хранить в индексе, и они используются только на выходе и никогда не используются для фильтрации/сортировки/группировки. С точки зрения управления ресурсами, хранение их в blob не является оптимальным. Примеры таких строк могут быть коды продуктов или UUID (которые должны быть уникальными, и сортировка по ним не имеет большого смысла). Перемещение их в хранимые поля сделает blob меньше, что означает меньшее использование ОЗУ, более быструю загрузку при старте и, в зависимости от ситуации, позволит использовать mlocking. Одной из 'проблем', которая может возникнуть здесь, является то, что новые поля могут играть роль в полнотекстовых совпадениях, которые не ищут в конкретных полях, поэтому может быть хорошей идеей использовать оператор поиска ignore field , чтобы исключить их из поиска.

Установить Manticore Search

Установить Manticore Search