Поисковый сервис на базе Manticore Search
Поисковый сервис на базе Manticore Search
Manticore Search — это база данных с открытым исходным кодом, предоставляющая возможности полнотекстового поиска.
Вопрос организации поискового сервиса Manticore Search обширен, рассмотрим общие принципы и утилитарные функции, подходящие для основных задач.
Что такое полнотекстовой поиск на базе Manticore Search?
Полнотекстовый поиск — поиск больших объёмов информации, в результате которого данные приводятся к одному нормализованному виду на основе морфологии (по однокоренным словам) и сохраняются в некую структуру.
Можно сохранить количество вхождений конкретного слова в тексте, его позицию в тексте и вес слова относительно всего текста. На основе полученных данных формируется поисковый индекс.
Преимущества Manticore Search
С помощью Manticore Search проще достичь релевантности поиска — можно искать слова, используя морфологические данные, пользовательские словоформы или лексическое значение.
Сбор данных из различных источников и унификация информации для поиска и выдачи клиенту — важное преимущество сервиса Manticore Search. Часто данные, которые мы пытаемся «вытащить», могут находиться в разных базах. Кроме того, источники данных могут быть разные — это могут быть MySQL, PostgreSQL, XML-файлы и так далее. Manticore позволяет собирать и агрегировать эти данные.
Manticore Search упрощает поиск — мы ищем данные по ранее сформированному индексу и обращаемся за поиском информации к одной заранее проиндексированной таблице.
В Manticore реализован распределенный индекс — он позволяет масштабироваться из коробки, формировать индекс на разных машинах и собирать их одновременно. Распределённый поисковый индекс подходит для работы с большим объемом данных и обеспечения отказоустойчивости.
Какие проблемы решает Manticore
Когда мы работаем с понятными сущностями — пользователь, товар, заказ — мы пользуемся привычными инструментами и известными алгоритмами. У таких объектов есть уникальные числовые идентификаторы, их легко сохранять, менять или удалять.
Как быть в случае, когда требуется получить срез данных по определенным критериям? Набор критериев может быть разным — например, нужно агрегировать информацию по разным фильтрам, в том числе кастомным.
Когда возникает такой запрос, появляются сложности его реализации: нужно обращаться к нескольким таблицам, искать по связям между сущностями, применять условия. Это увеличивает кодовую базу и риск появления ошибок.
Manticore умеет решать эту задачу — сервис позволяет определить, какие данные будут использоваться для сортировки или фильтрации.
Ещё одна частая проблема — конкурентный доступ к данным. Когда вы обращаетесь к таблице за поиском сущностей, может случиться так, что в этот момент в эту таблицу кто-то добавляет новые сущности, таблица может заблокироваться и запрос зависнет.
Чтобы не допустить этого, Manticore сохраняет копию источника данных, чтобы вы могли в любой момент времени получить к нему доступ.
Как работает Manticore Search?
Чтобы сохранить все слова и провести по ним поиск, Manticore предварительно анализирует:
- списки стоп-слов. На этом этапе отсеиваются слова, которые не влияют на поиск — предлоги, местоимения и т.д.;
- списки замены словоформ. Можно загрузить собственный словарь с актуальными и корректными для бизнес-задачи значениями слов, чтобы искать их по этому значению;
- морфологические и стемминг-словари на разных языках. Поиск можно производить по корню слова (морфология) или по грамматике (стемминг).
После этого все слова сохраняются и откладываются в Manticore Search. Теперь по ним можно производить полнотекстовой поиск.
В Manticore реализовано два подхода:
- Сбор данных из сторонних источников — Manticore забирает данные из баз данных и строит индекс по существующим данным. Такой формат можно назвать простым индексом.
- Индекс реального времени — индекс данных, получаемых из Manticore напрямую в реальном времени. Для такого индекса база Manticore используется именно в качестве основной — если вам нужно обеспечить максимальную оперативность актуализации данных, такой способ будет оптимальным.
Требования к входящим данным
У документа, который нужно индексировать, должны быть обязательные поля:
- ID — уникальный числовой идентификатор документа (int64). При хранении даже миллиона строк на неограниченном количестве серверов, ID документа будет уникальным независимо от источника данных;
- UpdatedAt — дата и время обновления документа. По этому параметру Manticore Search понимает, какие данные нужно обновить и как их сгруппировать;
- DeletedAt - дата и время удаления документа. Manticore не производит поиск по удалённым документам, но запоминает и фиксирует момент их удаления.
В Manticore очень много тонких настроек, поэтому дополнительные поля в индексируемых документах будут отличаться в зависимости от ваших задач.
Таблица 1 - Типы данных для простых индексов
Обозначение | Описание |
---|---|
sql_attr_bigint | 64 разрядные числа со знаком |
sql_attr_string | строки |
sql_attr_uint | 32 разрядные числа без знака |
sql_attr_float | дробные числа одинарной точности (иногда из-за отсутствия одинарной точности могут возникнуть проблемы, например, при получении цен с копейками) |
sql_attr_timestamp | дата и время в числовом виде |
sql_attr_bool | булево значение (в базе хранится как число 0 и 1), флаги |
sql_attr_json | json-данные |
Таблица 2 - Типы данных для индексов реального времени
Обозначение | Описание |
---|---|
rt_attr_bigint | 64 разрядные числа со знаком |
rt_attr_string | строки |
rt_attr_uint | 32 разрядные числа без знака |
rt_attr_float | дробные числа числа одинарной точности |
rt_attr_timestamp | дата и время в числом виде |
rt_attr_bool | булево значение, флаги |
rt_attr_json | json данные |
Как развернуть Manticore?
Существует два варианта установки Manticore — устанавливать на хост-машину или поднимать в docker-контейнере. Наша команда ТЕХНОНИКОЛЬ использует второй вариант — он более гибкий, масштабируемый и управляемый.
Для удобства работы наш ведущий разработчик Константин Шамиев написал приложение на golang, доступное в этом репозитории https://gitlab.tn.ru/golang/template/manticore. Задача этого приложения — взять на себя всю обслуживающую функцию, чтобы оно работало по системе чёрного ящика.
Алгоритм установки такой:
- используем docker-контейнер и собираем сервис-приложение;
- в рабочем образе настраиваем Manticore со всеми необходимыми компонентами (компоненты могут варьироваться в зависимости от задачи);
- после сборки получаем docker-образ и подключаем его.
Этот docker-образ предусматривает установку на хост-машину трёх основных хранилищ.
В первом хранилище складываются логи Manticore:
- лог работы сервис-приложения;
- лог поискового движка Manticore, в котором он пишет процесс индексации;
- лог запросов к сервису Manticore для получения информации.
Все логи вынесены на хост — так с ними проще работать.
Второе хранилище содержит индекс-дату, в которую будут попадать все проиндексированные данные.
Третье хранилище — конфигурационный файл Manticore. Он содержит данные о том, какие индексы нужно собирать.
Важно понимать, что сервис-приложение и Manticore будучи в одном docker-контейнере не мешают другу другу. Cервис-приложение работает как сторонний контроллер — оно индексирует данные, следит за работоспособностью Manticore, но при этом никак не влияет на запрос, который приходит от пользователя. Сам запрос попадает напрямую в Manticore.
Основные источники, из которых Manticore может брать данные «из коробки»:
- DB Postgress;
- DB MySQL;
- DB ODBC;
- CSV, XML.
Manticore работает по трем протоколам.
- port 9306 используется по умолчанию для MySQL-клиента для формирования запросов с помощью синтаксиса, поддерживаемого спецификацией MySQL;
- port 9308 — это протокол для HTTP/HTTPS. В Manticore можно напрямую с фронта обращаться к сервису поиска;
- port 9312 — бинарный протокол для взаимодействия между нодами и работы с распределённым индексом.
Масштабировать поиск можно при помощи использования разных нод — если все контейнеры связаны, Manticore может взять оттуда данные.
https://lh4.googleusercontent.com/awIYGi2K0COtp92-Vdq5qCe6wZqeU_ETTREueOvJZdkZ6yc6J-Z95jYVP6U_XRqPyXUtZKzji9nX_e7nz7d3wLuX3b9WE508zEfHxH_5v72-Xf2VssmU5fr9WoGVKK71Ffkf6TGh406BWaKyi1G521cjxBEpjFeEdNvZdZ5tqMd6DDsVmcG7pzqmem-12AКак устроен код для работы с Manticore?
Проще всего разобрать устройство кода на примере кейса, который работает для 90% задач.
Настроим несколько поисковых индексов:
1) основной индекс (main). Его задача — индексировать большой объём данных на текущий момент времени. Ротация производится редко, раз в месяц или в неделю;
2) вспомогательный индекс (delta). Он должен индексировать данные, изменённые в моменте времени. Ротация индекса каждые 5 минут;
3) объединённый индекс (distributed). Агрегирует main и delta, присваивая им собственный индекс.
Структура кода для задачи Manticore (на примере кейса с индексами main и delta) состоит из следующих блоков:
- данные для подключения;
- директивы для индексации;
- начальные настройки;
- настройки порционности сбора данных;
- поисковый запрос;
- пост-запросы для служебной отработки;
- блок настроек;
- код индекса.
Что важно знать про блок настроек?
Manticore глобально разделяет все данные на атрибуты и полнотекстовые данные. К полнотекстовым данным относятся строки с текстом, а все числа, даты и другие данные не текстового формата определяются как атрибуты. По ним невозможен полнотекстовой поиск, но атрибуты можно использовать как фильтр, например, по цене.
Manticore позволяет изменить эту настройку — вы можете добавить полнотекстовым данным функцию атрибутов или использовать полнотекстовые данные только для атрибуции, заменив их тип.
Кроме того, в блоке настроек можно отключить сохранение в Manticore исходных данных для оптимизации работы.
Как управлять порционностью сбора данных?
Чтобы Manticore справилась с объёмом данных для анализа, их нужно брать порционно. Для этого есть предназначены настройки:
- sql_range_step — количество строк данных, которое Manticore должна собрать в единицу времени;
- sql_ranged_throttle — время промежутка между сборами порций.
Индекс содержит следующие поля:
- тип индекса;
- место хранения в docker-контейнере;
- источник индексации;
- настройка поискового индекса.
Атрибуты настройки могут содержать стоп-листы (с указанием пути до файла или с помощью обращения к предустановленным стоп-листам), пользовательские словоформы, настройки морфологии языка.
Для сопутствующих индексов (таких как delta) не нужно дублировать код настройки — он наследует у родительского индекса (в нашем случае main) все общие параметры, поэтому для индекса delta достаточно только прописать его уникальные настройки.
Что ещё можно изучить про Manticore Search?
На сайте https://play.manticoresearch.com/ есть интерактивные курсы на тему различных решений. Но они подходят в основном для того, чтобы понять принципы работы Manticore.
Большая часть ответов, прикладные детали и параметры настроек содержатся в документации: https://manual.manticoresearch.com/Introduction.