Что ищут и не находят: как no-results превратился в наш главный источник задач
Мы добавили Elasticsearch в каталог на 28 000 SKU и решили, что дело сделано. Поиск работает, товары находятся, скорость нормальная. Через месяц я открыл аналитику поиска — конкретно логи no-results запросов.
Там было 340 уникальных фраз за одну неделю. «Кроссовки найк 42» — ноль результатов. «Куртка непромокаемая мужская» — ноль. «Переходник USB-C hub» — ноль.
Не потому что товара нет. Потому что индекс не знал, как его найти.
С тех пор no-results лог — первая вкладка, которую я открываю на ревью каталога. Не потому что там нужно всё чинить. Потому что там уже написано, что нужно сделать. Руками пользователей.
Почему no-results — честнее любого UX-исследования
Когда пользователь ищет что-то и не находит, он делает это намеренно. Он знает, что хочет. Он сформулировал запрос. Это не случайный клик по баннеру и не просмотр категории. Это декларация намерения.
UX-исследование, тепловая карта, опрос — всё это интерпретации. No-results запрос — это факт. Человек пришёл с конкретной потребностью и ушёл с нулём.
В каталоге с 10–30k SKU за неделю накапливается 200–400 таких фактов. Уникальных. Каждый указывает на конкретную проблему. Большинство команд эти данные не читает вообще.
Как собирать no-results запросы из Elasticsearch
Elasticsearch пишет поисковые запросы в slow log, но это не то, что нужно. Нужны запросы, которые вернули total.hits.value == 0.
Простой способ — на уровне приложения. Перехватываем ответ поискового запроса, смотрим на количество хитов. Если ноль — пишем запрос, timestamp, и контекст (категория, откуда пришёл пользователь) в отдельный индекс Elasticsearch или в обычный лог-файл.
В Bitrix + Elasticsearch это делается в компоненте поиска до рендеринга результатов. Структура записи минимальная:
{
"query": "кроссовки найк 42",
"timestamp": "2023-06-10T14:32:11Z",
"category_context": "shoes",
"user_type": "guest"
}
За неделю такой лог по активному каталогу даёт 500–800 записей. После дедупликации и агрегации — 200–400 уникальных запросов. Ровно столько, сколько нужно для одного рабочего ревью.
Три класса проблем, которые вскрывает лог
Когда начинаешь читать no-results запросы, быстро понимаешь: они делятся на три принципиально разных класса.
Синонимы и написание
Самый большой класс. «Найк» вместо «Nike», «USB-C» вместо «Type-C», «непромокаемая куртка» вместо «куртка Gore-Tex». Пользователь знает товар, но называет его иначе, чем вы. Это не его проблема — это ваша.
Elasticsearch синонимы решают этот класс. Но вручную составить словарь синонимов — задача, которая никогда не заканчивается. No-results лог решает её автоматически: там написано, что именно называют по-другому.
Проблемы в структуре каталога
Второй класс сложнее. «Корм для кошек с уриной» — ноль результатов. Товар есть. Но он находится в категории «корм» без тега «уринарная формула» в индексе. Пользователь ищет по характеристике, а каталог организован по бренду.
Такие запросы указывают на несоответствие ментальной модели пользователя и структуры каталога. Их не решишь одними синонимами — нужно либо добавить поля в индекс, либо пересмотреть, как атрибуты попадают в Elasticsearch.
Реальный товарный пробел
Третий класс: товара реально нет. «Кроссовки X brand размер 48» — у магазина нет этого размера. «Моноколесо» — категории нет вообще.
Это не баг поиска. Это сигнал для байера или для развития ассортимента. В одном из проектов топ-20 таких запросов за квартал прямо легли в план закупки следующего сезона. Не потому что кто-то анализировал рынок — просто прочитали, что искали люди, которые уже пришли на сайт.
Процесс: как мы разбираем лог на спринт
Раз в неделю, в понедельник. Выгружаем топ-50 no-results запросов за прошедшую неделю (по частоте). 20 минут на то, чтобы классифицировать каждый по трём классам выше.
Синонимы — сразу в Elasticsearch synonyms.txt. Обычно 5–10 штук за сессию, добавляются за 15 минут.
Структурные проблемы — в backlog с описанием, какое поле нужно добавить или исправить. Приоритет по частоте запроса.
Товарные пробелы — в отдельный список для закупки/ассортиментного менеджера. Там не наша зона, но данные им нужны.
Всё вместе — час в неделю. За три месяца такой работы no-results rate упал с 18% до 7%. Это не потому что мы сделали какой-то большой рефакторинг поисковой системы. Просто регулярно читали, что ищут и не находят.
Синонимы из живых запросов vs ручные словари
Стандартный подход: взять редактора, дать ему список категорий и попросить написать синонимы. Работает плохо по одной причине. Редактор угадывает, как могут называть товар. Пользователи не угадывают — они реально так называют.
Разница в качестве чувствуется быстро. Синонимы из no-results лога — это то, что реально мешало находить товар прямо сейчас. Ручные словари — это предположения о будущем.
В каталоге с 28k SKU за полгода работы с логами мы собрали словарь из 380 синонимных пар. Из них 70% мы бы никогда не придумали самостоятельно.
Метрики: как понять, что поиск становится лучше
Основной показатель — no-results rate. Отношение поисковых сессий с нулём результатов к общему числу поисковых сессий. На необработанном каталоге обычно 15–25%.
Параллельно смотрим на conversion rate тех, кто использовал поиск. Когда no-results rate падает, этот показатель растёт: пользователи, которые что-то ищут, приходят с конкретным намерением.
Третья цифра — доля запросов из топ-50 no-results, которые за неделю перестали быть нулевыми. Этот метрик плохо смотрится в дашборде, но честно отвечает на вопрос «мы вообще с этим работаем».
На проекте с 28k SKU движение с 18% до 7% no-results rate за квартал дало измеримый прирост по конверсии в категориях, где поиск использовался чаще всего. Не потому что мы переписали поиск. Потому что начали его читать.
Elasticsearch настроить можно за один день. Читать, что он говорит, придётся месяцами. No-results лог — первое место, куда стоит зайти, когда поиск уже работает.
Ещё о том, как поиск влияет на конверсию каталога: Elasticsearch — это не «база со скоростью». Это UX-инструмент. И о том, какие фасеты реально влияют на решение купить: Фасеты, которые продают.