Отметим: когда на сайте больше 100 000 страниц, стандартный SQL LIKE перестаёт справляться. Мы неоднократно сталкивались с проектами, где время поиска достигало 5–10 секунд, что отпугивает пользователей и снижает конверсию. Например, в одном проекте с каталогом на 3 млн товаров после внедрения Manticore среднее время поиска упало с 7 секунд до 35 мс, а нагрузка на сервер БД снизилась в 10 раз. Полнотекстовый поисковый движок вроде Manticore Search решает проблему — время ответа снижается до 20–50 мс. Мы используем Manticore Search 6.x в Docker с PHP 8.x и PDO. Опыт более 5 лет и 30+ успешных интеграций. Мы подключаем и настраиваем Manticore под ваш проект.
Какие проблемы решаем?
- Медленный поиск при большом объёме данных. Manticore обрабатывает запросы к индексам объёмом в сотни гигабайт за миллисекунды. Типичный SQL-запрос с LIKE вызывает полное сканирование таблицы и N+1 проблему — Manticore избегает этого благодаря инвертированным индексам.
-
Сложная морфология русского языка. Встроенный стеммер
stem_ruи лемматизаторlemmatize_ru_allкорректно обрабатывают падежи и словоформы. Настройка обязательна для русскоязычного контента. - Необходимость ранжирования результатов. Настраиваем веса полей, BM25, взвешивание по рейтингу и дате — поиск выдаёт самое релевантное первым. Например, заголовок статьи имеет вес 10, тело — 1, автор — 2.
- Синхронизация с основной базой данных. Реализуем event-driven обновление индекса через Observer или batch-индексацию. Без синхронизации поиск выдаёт устаревшие данные.
Почему Manticore лучше Sphinx для новых проектов?
Manticore активно развивается: поддерживает JSON-документы, HTTP API, колоночное хранилище. Скорость поиска на 20–30% выше благодаря оптимизациям в 6.x. Elasticsearch уступает Manticore по производительности на простых полнотекстовых запросах в 2–3 раза, а лицензионные затраты ниже. Согласно официальной документации Manticore, скорость поиска на RT-индексах достигает 10 000 запросов в секунду. Если у вас legacy Sphinx — мы поможем мигрировать на Manticore без остановки сервиса.
Что даёт морфология для русского языка?
Отметим: как указано в документации Manticore по морфологии, стеммер stem_ru и лемматизатор lemmatize_ru_all обеспечивают корректное распознавание падежей и словоформ. Без этой настройки поиск не найдёт «автомобиля» по запросу «автомобиль» или «автомобилей». Это критично для русскоязычного контента.
Как мы настраиваем поиск: стек и пример
Используем Manticore Search 6.x, Docker, PHP 8.x с PDO. В типичном проекте мы разворачиваем контейнер, настраиваем RT-индекс с морфологией для русского языка, подключаем через MySQL-протокол. Ниже — конфигурация и пример кода.
Установка Manticore Search
# docker-compose.yml services: manticore: image: manticoresearch/manticore:6.2.12 environment: - EXTRA=1 ports: - "9306:9306" # MySQL-совместимый порт - "9308:9308" # HTTP API volumes: - manticore_data:/var/lib/manticore - ./manticore.conf:/etc/manticoresearch/manticore.conf Конфигурация индекса
# manticore.conf index articles { type = rt path = /var/lib/manticore/articles rt_field = title rt_field = body rt_field = author rt_attr_uint = category_id rt_attr_bigint = created_at rt_attr_float = rating rt_attr_string = slug morphology = stem_ru, stem_en min_word_len = 2 expand_keywords = 1 min_infix_len = 3 stopwords = /etc/manticoresearch/stopwords_ru.txt } searchd { listen = 0.0.0.0:9306:mysql41 listen = 0.0.0.0:9308:http log = /var/log/manticore/searchd.log query_log = /var/log/manticore/query.log max_matches = 10000 } Подключение через MySQL-протокол (PHP)
$pdo = new PDO('mysql:host=localhost;port=9306;charset=utf8', '', ''); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Вставка документа $stmt = $pdo->prepare(" INSERT INTO articles (id, title, body, author, category_id, created_at, rating) VALUES (:id, :title, :body, :author, :category_id, :created_at, :rating) "); $stmt->execute([ 'id' => $article->id, 'title' => $article->title, 'body' => strip_tags($article->content), 'author' => $article->user->name, 'category_id' => $article->category_id, 'created_at' => $article->created_at->timestamp, 'rating' => $article->rating, ]); // Полнотекстовый поиск с весами полей $stmt = $pdo->prepare(" SELECT id, title, author, rating, WEIGHT() AS relevance FROM articles WHERE MATCH(:query) ORDER BY relevance DESC, rating DESC LIMIT :offset, :limit OPTION ranker=bm25, field_weights=(title=10, body=1, author=2) "); Синхронизация с базой данных
class ArticleObserver { public function saved(Article $article): void { ManticoreIndexJob::dispatch($article->id); } public function deleted(Article $article): void { ManticoreDeleteJob::dispatch($article->id); } } Подсветка результатов (snippet)
SELECT id, title, SNIPPET(body, :query, 'limit=200, around=5, html_strip_mode=strip') AS excerpt FROM articles WHERE MATCH(:query) LIMIT 20 Процесс работы
- Анализ требований к поиску: объём данных, типы контента, нужна ли морфология.
- Проектирование схемы индекса: поля, атрибуты, веса.
- Развёртывание Manticore в Docker, настройка конфигурации.
- Написание кода для индексации: первоначальная загрузка, инкрементальное обновление.
- Реализация API поиска в приложении с ранжированием и сниппетами.
- UI: окно поиска, результаты, пагинация, подсветка найденного.
- Тестирование: нагрузочное тестирование, проверка релевантности.
- Деплой и мониторинг.
Что входит в работу
- Установка и конфигурация Manticore Search в Docker.
- Создание RT-индекса с настройкой морфологии, стоп-слов, инфиксов.
- Написание модуля синхронизации данных (Observer или batch).
- REST API для поиска (SQL или JSON).
- Адаптация фронтенда: строка поиска, сниппеты, пагинация.
- Нагрузочное тестирование и оптимизация.
- Документация по эксплуатации и доступам.
Сроки
| Этап | Время |
|---|---|
| Установка и конфигурация | 1 день |
| Первичная индексация + синхронизатор | 2 дня |
| API поиска + тесты | 2 дня |
| UI-интеграция | 1–2 дня |
| Итого | 6–7 рабочих дней |
Типичные ошибки и их решения
| Ошибка | Решение |
|---|---|
| Неправильная настройка морфологии (поиск не находит словоформы) | Указывать morphology = stem_ru, lemmatize_ru_all |
| Отсутствие стоп-слов (индекс засоряется предлогами) | Добавить файл stopwords со списком служебных слов |
| Синхронизация не настроена (поиск выдаёт устаревшие данные) | Реализовать Observer для событий сохранения/удаления |
Слишком малый лимит max_matches (обрезка результатов) | Увеличить до 10 000 или требуемого значения |
| Отсутствие сниппетов (пользователь не видит контекст) | Использовать функцию SNIPPET() в запросе |
Обеспечение синхронизации индекса в реальном времени
Используем паттерн Observer: при сохранении или удалении записи в Eloquent (Laravel) диспатчим Job на обновление индекса. В случае batch-загрузки больших объёмов данных применяем фоновый процесс, который индексирует пачки по 1000 записей. Это позволяет держать индекс актуальным без задержек.
Заказ интеграции поиска
Свяжитесь с нами для консультации и оценки вашего проекта. Мы проанализируем структуру данных, нагрузку и требования к поиску, предложим оптимальное решение. Работаем под ключ за 6–7 дней. Гарантируем стабильность и релевантные результаты. Получите консультацию по интеграции Manticore в ваш проект уже сегодня.







