Фасетный поиск на Elasticsearch для большого каталога

Автор: WebGoodPeople

Проблема при масштабировании

Стандартный поиск 1С-Битрикс работает приемлемо до отметки 300–500 SKU. При переходе за этот порог начинаются системные проблемы, которые невозможно решить настройкой — только заменой подсистемы.

Конкретные симптомы: поиск по полной фразе находит товар, а поиск по части слова — нет. Нет поддержки синонимов: «арматура» и «пруток» не связаны. Фильтры строятся через SQL LIKE-запросы к таблицам инфоблоков — при 20 000 товарах и 8 активных фильтрах одновременно время ответа превышает 800 мс, а при высокой нагрузке база падает в deadlock. Релевантность выдачи не настраивается: все совпадения равнозначны, позиция товара в результатах непредсказуема. Нулевой результат (zero-results) на проекте УралМеталл до оптимизации составлял 22% от всех поисковых запросов.

Почему Elasticsearch подходит

Elasticsearch построен на инвертированном индексе — структуре данных, изначально созданной для полнотекстового поиска. Это даёт несколько принципиальных преимуществ по сравнению с реляционной БД.

  • Агрегации для фасетов. ES считает количество товаров по каждому значению атрибута за один запрос, без дополнительных JOIN. Именно так работают счётчики рядом с каждым значением фильтра («Диаметр: 12 мм (47)»).
  • Настраиваемая релевантность. Можно указать, что совпадение в названии товара весит в 3 раза больше, чем в описании. Можно поднять в выдаче товары с остатком.
  • Синонимы и стемминг. Словарь синонимов подключается на уровне анализатора: «уголок» и «угловой профиль» становятся взаимозаменяемыми без изменения данных.
  • Автодополнение. Поле типа completion даёт подсказки при наборе за 5–10 мс.
  • Zero-downtime переиндексация. Новый индекс собирается параллельно со старым, затем алиас переключается атомарно — пользователь не видит перебоя.

Архитектура: Битрикс как источник данных

Bitrix остаётся единственным источником правды о товарах — мы не дублируем логику управления каталогом. Схема синхронизации:

  • При сохранении товара или изменении цены в Битрикс срабатывает обработчик события OnAfterIBlockElementUpdate, который ставит ID товара в очередь.
  • Агент Битрикс (или внешний cron) обрабатывает очередь каждые 2 минуты: забирает данные товара через CIBlockElement::GetByID, формирует JSON-документ и отправляет в ES через bulk API.
  • Next.js запрашивает Elasticsearch напрямую для страниц каталога, поиска и фильтрации — без обращения к Битрикс.
  • Добавление в корзину, оформление заказа и авторизация остаются на тонких PHP-эндпоинтах Битрикс.

Такая архитектура означает, что задержка между изменением товара в Битрикс и отображением на сайте составляет максимум 2–3 минуты. Для B2B-каталога металлопроката это приемлемо.

Ключевые технические приёмы

Filter-aware aggregations. Это главная сложность фасетного поиска: когда пользователь выбирает фильтр «Диаметр: 12 мм», счётчики остальных фильтров должны пересчитаться с учётом этого выбора. В ES это реализуется через post_filter + отдельные агрегации с собственным фильтром для каждого атрибута. Реализация нетривиальна, но это единственный правильный подход.

Field boosting. В маппинге индекса мы задаём веса полей:

"query": {
  "multi_match": {
    "query": "арматура 12",
    "fields": ["title^3", "article^2", "description", "tags^1.5"]
  }
}

Вложенные агрегации для иерархических категорий. Подкатегории считаются через nested aggregation — один запрос возвращает дерево категорий с количеством товаров на каждом уровне.

Реальные числа: проект УралМеталл

После замены битриксового поиска на Elasticsearch:

  • Время ответа поиска: с 800 мс до 45 мс (медиана по production-логам)
  • Количество одновременно активных фильтров: с 3 до 47 — стало технически возможным без деградации производительности
  • Zero-results rate: с 22% до 4% — за счёт синонимов и нечёткого поиска (fuzziness: AUTO)
  • Конверсия из поиска в карточку товара: +18% — пользователи находят нужное с первой попытки чаще

Когда Elasticsearch не нужен

ES — это дополнительная инфраструктура: отдельный сервис, индексы, синхронизация. Это имеет смысл при каталоге от 1 000–2 000 SKU с комплексными атрибутами и высокой поисковой нагрузкой.

Если у вас каталог до 300 SKU с 3–4 простыми атрибутами и умеренным трафиком — стандартный поиск Битрикс справится. Не усложняйте без необходимости.

Хотите проверить, нужен ли вашему проекту Elasticsearch? В рамках Catalog Probe мы за 3 дня разворачиваем proof-of-concept на реальных данных вашего каталога и показываем разницу в скорости и качестве поиска.

Расскажите нам о своем проекте

Наши офисы

  • Россия
    Россия, Санкт-Петербург, Рижская улица, 5, корп. 1 офис 402
    +7 (967) 555-90-32
  • Казахстан
    Алма-Ата
    +7 (707) 340-29-12