Жалоба приходит почти всегда от самого владельца: «ввёл в поиск название товара, который точно есть, — ничего не нашлось». Проверяешь — товар в каталоге, в наличии, карточка открывается по прямой ссылке. Просто поиск его не видит. Это не баг и не случайность: в большинстве каталогов поиска как такового нет, есть подстановка строки в SQL-запрос. Разберём, чем они отличаются и в каком порядке это чинится.
Что обычно стоит под видом поиска
В девяти проектах из десяти, где поиск «не работает», под капотом лежит одна строка: WHERE name LIKE '%запрос%'. Иногда с добавлением описания и артикула через OR. Это честный способ найти точную подстроку — и ровно то, что люди никогда не вводят.
Такой поиск гарантированно не находит товар в следующих случаях:
- Слово в другой форме: в каталоге «шуруповёрт аккумуляторный», ищут «шуруповёрты аккумуляторные»
- Слова переставлены: «аккумуляторный шуруповёрт» — подстроки целиком уже нет
- Опечатка в одной букве — «шурупорверт»
- Артикул введён без дефиса или с пробелом вместо дефиса
- Бренд написан кириллицей, а в базе латиницей
- Между словами запроса в названии стоит что-то ещё: «кабель ВВГ 3х2.5» против «кабель силовой ВВГнг-LS 3х2.5»
И отдельно — скорость. Шаблон с ведущим процентом не может использовать обычный B-tree индекс: база проходит таблицу целиком. На тысяче товаров это незаметно, на пятидесяти тысячах с описаниями поиск начинает занимать секунды и ложится в одну очередь с остальными запросами страницы.
Поиск — это не фильтр по названию. Это отдельная подсистема со своим индексом, своими правилами разбора запроса и своим ранжированием. Пока её нет, улучшать нечего: можно только по-разному проигрывать.
Морфология: главная причина пустых результатов
Русский язык даёт у одного слова до десятка форм. Чтобы «шуруповёрты» нашли «шуруповёрт», запрос и индекс должны приводиться к одной базовой форме. Делается это двумя способами.
Стемминг отрезает окончания по правилам — для русского это алгоритм Портера или его варианты. Работает без словаря и быстро, но грубо: склеивает то, что склеивать не надо, и не справляется с чередованиями в корне.
Лемматизация приводит слово к словарной форме по морфологическому словарю. Точнее, но требует словаря в сборке движка. Для русскоязычного каталога это заметно лучший результат, особенно на технических запросах.
Практический вывод один: морфология — не настройка галочкой в админке, а свойство поискового движка. Если его нет, падежи не победить ни синонимами, ни правкой названий.
Три уровня решения и когда какой брать
Полнотекстовый индекс самой базы. В MySQL это FULLTEXT индекс и конструкция MATCH ... AGAINST, в InnoDB работает начиная с 5.6. Он даёт разбор на слова, стоп-слова, логический режим с плюсами и минусами и релевантность вместо простого «нашлось или нет». Чего он не даёт — русской морфологии: встроенных стеммеров для русского там нет. Плюс мешает порог длины токена (innodb_ft_min_token_size, по умолчанию 3), из-за которого короткие значимые слова и части артикулов просто не попадают в индекс.
В PostgreSQL ситуация лучше: tsvector с конфигурацией russian стеммит русский из коробки, индексируется GIN-индексом, а для опечаток и частичных совпадений рядом ставится pg_trgm с триграммным индексом. Для каталога до нескольких десятков тысяч позиций этого обычно достаточно, и внешний сервис можно не поднимать.
Выделенный поисковый движок. Manticore (развитие Sphinx), Elasticsearch и OpenSearch, Meilisearch, Typesense. Они дают морфологию со словарями, исправление опечаток, синонимы, настраиваемые веса полей, ранжирование по BM25, подсказки и фасеты по тем же данным. Цена — отдельный процесс, который надо держать живым, и индексация, которую надо синхронизировать с каталогом.
Встроенные механизмы CMS. У 1С-Битрикс есть свой модуль поиска с морфологией и индексом по всем сущностям — его достаточно, пока каталог не разросся, но на больших объёмах переиндексация становится тяжёлой, и его меняют на внешний движок. В WooCommerce штатный поиск — это как раз LIKE по заголовку и контенту, поэтому там вопрос встаёт раньше всего. Про то, как это соотносится с выбором платформы, мы писали в разборе CMS или свой фреймворк.
По каким полям искать, кроме названия
Запрос в каталоге — это не всегда название. Люди вводят артикул, модель, бренд, характеристику или всё вперемешку. Минимальный набор полей, который должен попадать в индекс:
- Название — максимальный вес
- Артикул и производственный код — точное совпадение в самый верх, минуя ранжирование
- Бренд и модель — отдельным полем, а не внутри названия
- Значимые свойства: сечение, размер, мощность, цвет
- Название категории — чтобы «ламинат дуб» находил позиции, у которых слова «ламинат» в названии нет
- Описание — минимальным весом, иначе мусор из текстов вытеснит товары
Отдельная история с артикулами. Их вводят как попало: с дефисами, без, с пробелами, в другом регистре. Лечится нормализацией с двух сторон: при индексации и при разборе запроса из артикула убираются все разделители и регистр, и сравнение идёт по «склеенной» форме. Тогда ВВГ-3х2.5, ВВГ 3Х2,5 и ввг3х2.5 приводят к одному результату.
Там же решаются две мелочи, которые дают неожиданно много находок: транслитерация брендов в обе стороны («Tarkett» ↔ «Таркетт») и исправление раскладки, когда человек набрал запрос, забыв переключить язык.
Опечатки: полезно, но дозированно
Нечёткий поиск считает расстояние редактирования между словом запроса и словом индекса: сколько символов надо заменить, вставить или удалить. Расстояние 1 ловит большинство реальных опечаток, расстояние 2 начинает приносить мусор.
Правила, которые стоит заложить сразу:
- Слова короче пяти символов — без нечёткости вообще, иначе «бра» найдёт «бур»
- Артикулы и коды — только точное совпадение, нечёткость к ним не применяется
- Нечёткий вариант ранжируется ниже точного, а не наравне
- Сначала ищем строго, и только при пустом результате повторяем запрос с допуском
Последний пункт — главный. Нечёткость, включённая всегда и для всех слов, портит хорошие запросы ради спасения плохих: по точному названию в выдачу подмешиваются соседние товары, и поиск начинает выглядеть случайным.
Ранжирование: что показывать первым
Найти — половина задачи. Вторая половина — порядок. Базовая релевантность по BM25 учитывает, насколько редкое слово совпало и в каком поле, но её почти всегда приходится дополнять бизнес-правилами:
- Товар в наличии — выше отсутствующего
- Карточка с ценой — выше карточки «цена по запросу»
- Позиции без картинки и без описания — ниже
- Точное совпадение артикула — первым, независимо от остального
- Популярные позиции — выше при равной релевантности
Чего делать не стоит — прятать товары не в наличии из поиска совсем. Человек ищет конкретную позицию; если её нет, он должен увидеть карточку с ценой, сроком поставки и возможностью оставить заявку, а не пустую страницу. Да и страницы, выпавшие из поиска по сайту, со временем начинают выпадать и из выдачи поисковых систем. Как устроена карточка, которая при этом ещё и приводит трафик, разбирали отдельно: карточка товара в поиске.
Подсказки и поиск вместе с фильтром
Подсказки под строкой ввода — это отдельный, более быстрый запрос по префиксу, обычно по урезанному индексу: название, бренд, категория. Работающая настройка выглядит так: задержка 150–250 мс после последнего нажатия, обрыв предыдущего запроса, не больше восьми-десяти результатов, в каждом — картинка и цена, плюс отдельной группой категории. Запросы короче трёх символов не отправляются вообще.
Вторая типовая поломка — отношения поиска и фильтра. Правильный порядок: сначала поисковый запрос даёт набор товаров, затем фасеты считаются внутри этого набора и применяются к нему. Часто бывает наоборот: человек выбрал фильтр на странице результатов, и поисковый запрос потерялся — он снова видит всю категорию. Проверяется это за минуту и чинится в параметрах ссылки фильтра.
Индексация: когда данные устают
Отдельный индекс живёт отдельно от каталога, и его надо обновлять. Схема, которая работает: полная переиндексация по расписанию раз в сутки ночью плюс дельта-индекс каждые несколько минут по изменившимся позициям. Для больших каталогов это не роскошь, а единственный способ не ждать полчаса после каждой правки.
Важная связка, про которую забывают: переиндексация должна запускаться после обмена с учётной системой, а не по независимому расписанию. Иначе ночью приехали новые товары и цены, а поиск отдаёт их только к следующей ночи. Если обмен с 1С у вас уже настроен, добавить в конец импорта вызов переиндексации — работа на один вечер, а эффект заметный.
Лог нулевых запросов — то, с чего надо начинать
Прежде чем менять движок, стоит узнать, что именно люди не находят. Для этого включается сохранение поисковых запросов с числом результатов: запрос, количество найденного, дата. Через пару недель берётся список запросов с нулём результатов, отсортированный по частоте.
Этот список обычно распадается на четыре группы, и каждая лечится по-своему:
- Товара действительно нет в каталоге — это заявка на расширение ассортимента, а не на доработку поиска
- Товар есть, но называется иначе — лечится синонимами и правкой названий
- Товар есть, запрос в другой форме или с опечаткой — лечится движком
- Запрос не про товар: «доставка», «гарантия», «самовывоз» — лечится правилом «запрос → страница»
Последняя группа почти всегда недооценена. Ручные правила, которые по конкретному запросу отдают нужную категорию или страницу доставки, закрывают часть обращений без всякой разработки и настраиваются контент-менеджером.
Страница «ничего не найдено»
Если результат всё-таки пуст, пустой экран — худший из возможных ответов. Что должно быть на этой странице: сам запрос с возможностью исправить, вопрос «может быть, вы искали…» с похожими по триграммам вариантами, популярные категории, телефон и форма «не нашли нужное — напишите, подберём». И запрос обязательно попадает в лог.
Человек, который не нашёл товар через поиск, в каталог руками не пойдёт. Он уйдёт в выдачу и откроет следующий сайт — поэтому поиск относится не к удобству, а к продажам.
Проверка поиска за пятнадцать минут
Этот набор проверок можно сделать на любом каталоге прямо сейчас, без доступа к коду:
- Ввести название товара в другом падеже и во множественном числе
- Переставить два слова запроса местами
- Ввести артикул с дефисом, без дефиса и с пробелом
- Написать бренд латиницей и кириллицей
- Сделать одну опечатку в середине слова
- Ввести «категория + свойство»: «кабель 2.5», «ламинат 33 класс»
- Выбрать фильтр на странице результатов и проверить, что запрос не потерялся
- Посмотреть, что показывает страница при пустом результате
- Проверить подсказки: появляются ли, с какой задержкой, есть ли в них цена
- Поправить товар в админке и посмотреть, через сколько правка появится в поиске
Если из десяти пунктов проваливается больше трёх, вопрос не в донастройке, а в том, что поискового движка в проекте нет. Это понятный объём работы с предсказуемым результатом: индекс, морфология, веса полей, нормализация артикулов, подсказки, лог запросов.
Мы ставим поиск на каталоги любой величины: от полнотекстового индекса в базе для магазина на несколько тысяч позиций до выделенного движка с фасетами на десятки тысяч. Делаем это и внутри разработки интернет-магазина, и отдельной задачей на существующем сайте — включая каталоги и порталы, где поиск становится основным способом навигации. Если непонятно, что именно у вас не находится, начинать стоит с юзабилити-аудита и лога нулевых запросов: он почти всегда показывает, что половина проблем решается без переписывания.
Набор запросов для приёмки поиска по каталогу
Составьте проверочный список до изменения поиска и сохраните результаты. После доработки используйте тот же набор: иначе легко улучшить один показательный запрос и пропустить остальные сценарии. Для магазина запчастей особенно важны артикулы и совместимость — этот подход применялся в каталоге ПромСнабЮг.
- Точный артикул существующего товара: нужная карточка должна находиться без обязательного ввода названия.
- Тот же артикул с пробелом или дефисом, если такой вариант встречается у покупателей. Нормализация не должна смешивать разные реальные номера.
- Название с одной типичной опечаткой: проверьте, не вытесняют ли случайные совпадения точный результат.
- Номер аналога или кросса: результат ожидается только если связь действительно заведена в данных.
- Неизвестный номер: понятное сообщение и возможность отправить запрос на подбор.
- Товар, скрытый от публикации: поведение должно соответствовать настройкам видимости и правилам магазина.
Отдельно проверьте телефон: видимость поля, клавиатуру, открытие карточки и возврат к результатам. При доработке поиска пришлите 5–10 реальных запросов с ожидаемыми карточками. Для конкретной CMS можно выбрать доработку WordPress/WooCommerce или 1С-Битрикс.