Начиная с версии 3.2.0 Manticore Search представил новую функцию — Хранение документов.
Исторически Manticore Search был поисковым движком, который индексирует тексты, но не сохраняет оригиналы. Текст обрабатывается, преобразуясь из простой строки в специальные структуры, формирующие полнотекстовый индекс, позволяющий быстро искать по тексту. В наборе результатов пользователь не получал оригинальный текст, поскольку его восстановление из полнотекстового индекса может быть сложным процессом. Кроме того, настройки индексации могут включать условия, запрещающие индексацию определённых слов (например, минимальная длина слова или стоп‑слова), что делает восстановление невозможным.
Рабочий процесс поиска был создан для выполнения полнотекстового поиска в Manticore, а затем, основываясь на наборе результатов, выполнять дополнительный запрос к оригинальному источнику данных (база данных или файлы), чтобы получить содержимое, которое было только проиндексировано в Manticore. В некоторых случаях дополнительный запрос необходим не только для получения «отсутствующих» текстов, но и других данных, не включённых в индекс, потому что они не используются в поисковых операциях, и эти данные лишь увеличивали бы (необязательно) размер индекса. Однако существует множество случаев, когда единственной целью запроса является получение «отсутствующих» текстов, что рассматривается как лишний шаг, который было бы хорошо устранить — это упрощает код приложения, снижает дополнительную нагрузку, потребление ресурсов и устраняет ещё одну точку отказа в системе хранения данных.
Есть также сценарии, когда оригинальные данные не находятся в традиционной базе данных, и получение оригинальных текстов во время запроса может быть медленным. Требование хранить эти данные в базе данных может восприниматься как нежелательное и как единственная причина использовать базу данных для компенсации неспособности поискового движка хранить оригинальное содержимое. Такие сценарии могут включать:
- компания может захотеть искать тексты в офисных документах, таких как Word или PDF — они могут быть частью внутренних инструментов или портала, предлагающего научные, юридические или технические статьи.
- данные поступают из веб‑сервиса или из проиндексированных страниц.
- потоковые данные, которые могут быть журналами, сообщениями или электронными письмами. Чтение их из источников может быть сложным, поскольку во многих случаях они хранятся в распределённых системах, и чтение их во время запроса усложняет код приложения.
Вы можете пройти наш интерактивный курс , чтобы узнать, как использовать не только индексацию, но и хранение содержимого документов.
Теперь возможно хранить оригинальные тексты и возвращать их в результатах.
Следует отметить, что функция DS не превращает Manticore в традиционную базу данных. Manticore поддерживает транзакции и восстановление из binlog, и хотя он предоставляет большинство свойств ACID, он не считается настоящей ACID‑совместимой базой данных.
На данный момент также нет шифрования для хранения. Чувствительные или критические данные, такие как учётные данные пользователей или платёжные транзакции, не считаются подходящими для хранения в Manticore. Кроме того, существуют функции традиционных баз данных, такие как JOIN‑ы, которые пока не поддерживаются. Мы планируем работать над этим в будущих версиях.
Тем не менее, существует множество случаев, когда использование Manticore только для хранения данных или хранения без выполнения дополнительных запросов имеет большой смысл.
Хранение документов может снизить нагрузку на оригинальное хранилище данных или уменьшить требования к пространству.
Другой аспект на момент написания этой статьи — производительность хранения документов. Мы ожидаем значительно улучшить этот аспект в следующих релизах.
Usage
Хранение может быть включено с помощью директивы индекса 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 .
Advanced tuning
Тексты хранятся в отдельном файле на диске. По умолчанию они сжаты алгоритмом lz4. Доступен альтернативный алгоритм lz4hc, или сжатие может быть отключено ('none') путём установки директивы индекса 'docstore_compression'. Для алгоритма 'lz4hc' уровень сжатия можно настроить директивой docstore_compression_level, которая принимает значения от 1 до 12 (по умолчанию 9). Тексты сжаты на диске блоками. Размер блока можно настроить директивой docstore_block_size. Значение по умолчанию — 16k. Увеличение размера блока улучшит коэффициент сжатия и сэкономит больше места на диске, тогда как уменьшение размера блока должно повысить скорость доступа.
Когда поиск требует текста из хранилища, блок, содержащий его, читается с диска и распаковывается. Поскольку блок может содержать тексты из нескольких документов, распакованные блоки могут кэшироваться в памяти. По умолчанию используется кэш размером 16 МБ на весь демон. Размер кэша можно изменить настройкой docstore_cache_size в searchd.
Differences from string attributes
Manticore Search уже поддерживал тип данных , способный хранить и извлекать тексты в наборе результатов, а также использовать их для сравнения, фильтрации регулярными выражениями, сортировки и агрегирования. Более того, в случае индексов Real-Time можно использовать одно и то же имя для полнотекстового поля и строкового атрибута. Возникает вопрос о назначении сохранённых полей.
Строковые атрибуты хранятся в компоненте 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 , чтобы исключить их из поиска.
