Содержание
Для поиска на сайте с каталогом до сотен тысяч записей обычно хватает встроенного полнотекстового поиска PostgreSQL. Отдельный движок — Meilisearch или Elasticsearch — нужен, когда важны мгновенный поиск по мере ввода, устойчивость к опечаткам, сложные фильтры с подсчётом и релевантность, которую настраивают без программиста.
Разберём, чем плох поиск через LIKE, что умеет база данных, когда переходить на отдельный движок и как сделать поиск удобным.
Почему LIKE — это не поиск?
Запрос с LIKE '%слово%' ищет точное совпадение подстроки: он не понимает формы слов, не прощает опечаток, не сортирует по релевантности и на больших таблицах не использует обычные индексы. Пользователь ищет «красные кроссовки», а в базе «кроссовок красного цвета» — и получает пустую страницу.
Нормальный поиск должен уметь:
- находить разные формы слова: «кроссовки», «кроссовок», «кроссовкам»;
- прощать опечатки и неправильную раскладку;
- сортировать результаты по релевантности, а не по дате;
- учитывать синонимы и сокращения;
- совмещать текстовый запрос с фильтрами по цене, категории и наличию.
Что умеет полнотекстовый поиск PostgreSQL?
PostgreSQL умеет искать по словам с учётом морфологии, ранжировать результаты и использовать для этого индекс. Для нечёткого поиска по опечаткам подключают расширение триграмм. Плюс подхода — не нужна отдельная система: данные и поиск в одном месте, синхронизировать ничего не надо.
ALTER TABLE products ADD COLUMN search tsvector
GENERATED ALWAYS AS (
setweight(to_tsvector('russian', coalesce(title, '')), 'A') ||
setweight(to_tsvector('russian', coalesce(description, '')), 'B')
) STORED;
CREATE INDEX products_search_idx ON products USING GIN (search);
SELECT id, title, ts_rank(search, query) AS rank
FROM products, websearch_to_tsquery('russian', 'красные кроссовки') query
WHERE search @@ query
ORDER BY rank DESC
LIMIT 20;
Подробнее про индексы — в статье индексы в PostgreSQL, а про выбор СУБД — в материале PostgreSQL или MySQL.
Фото: Unsplash
Когда нужен отдельный поисковый движок?
Отдельный движок нужен, когда поиск — ключевая функция продукта: интернет-магазин с большим каталогом, маркетплейс, база знаний. Он даёт результаты по мере ввода за десятки миллисекунд, хорошо прощает опечатки и считает количество товаров в каждом фильтре.
| Критерий | PostgreSQL | Meilisearch | Elasticsearch / OpenSearch |
|---|---|---|---|
| Отдельная инфраструктура | Не нужна | Один сервис | Кластер |
| Опечатки | Через расширение | Из коробки | Настраивается |
| Поиск по мере ввода | Возможен, но сложнее | Из коробки | Настраивается |
| Фасеты и подсчёт по фильтрам | Вручную | Из коробки | Из коробки |
| Объём данных | До миллионов строк | Миллионы документов | Очень большие объёмы, логи |
| Сложность поддержки | Низкая | Низкая | Высокая |
Meilisearch и похожие движки хороши для каталогов и сайтов: их быстро подключить, а качество из коробки высокое. Elasticsearch и OpenSearch выбирают, когда данных очень много, нужна сложная аналитика или поиск по логам.
Как синхронизировать данные с поисковым индексом?
Данные синхронизируют через события: при создании, изменении или удалении записи в базе фоновая задача обновляет документ в индексе. Источником правды остаётся база данных, а индекс в любой момент можно перестроить с нуля.
Правила синхронизации:
- Обновляйте индекс через очередь, а не прямо в запросе пользователя.
- Держите команду полной переиндексации — она понадобится при изменении настроек.
- Индексируйте только поля, по которым ищут и фильтруют, а не всю запись.
- Следите за отставанием индекса от базы и ошибками задач.
Как сделать поиск удобным для пользователя?
Поиск удобен, когда он отвечает быстро, понимает человеческие формулировки и не оставляет пустую страницу. Даже идеальная технология не спасёт, если в данных нет нужных слов, а результаты нельзя отфильтровать.
Что помогает:
- подсказки по мере ввода и исправление раскладки;
- синонимы: «ноутбук» и «лэптоп», «телефон» и «смартфон»;
- фильтры с количеством результатов рядом с каждым значением;
- вместо пустой страницы — похожие товары или популярные категории;
- аналитика запросов без результатов, чтобы дополнять данные и синонимы.
Как собирать такие данные, мы разбирали в статье продуктовые метрики после запуска.
Коротко
LIKEне понимает формы слов, опечатки и релевантность — это не поиск.- Для большинства сайтов хватает полнотекстового поиска PostgreSQL.
- Отдельный движок нужен, когда поиск — ключевая функция: мгновенные подсказки, опечатки, фасеты.
- Индекс обновляют через очередь, а база остаётся источником правды.
- Качество поиска улучшают синонимы, фильтры и анализ запросов без результатов.
Частые вопросы
Поддерживает ли поиск PostgreSQL русский язык?
Да, в PostgreSQL есть словари для русского языка: поиск учитывает разные формы слов. Опечатки из коробки он не исправляет, для этого подключают расширение для нечёткого поиска по триграммам.
Сколько стоит отдельный поисковый движок?
Сам движок может быть бесплатным, но добавляет сервер, мониторинг и синхронизацию данных. Для небольшого каталога это несколько дней разработки и небольшой сервер, для крупного — отдельная инфраструктура.
Как понять, что поиск работает плохо?
Смотрите на запросы без результатов и на долю поисков, после которых пользователь ничего не открыл. Эти два отчёта быстро показывают, каких синонимов и данных не хватает.



