← Все статьи
Riders AgencyТексты и контент-редакторы

Поиск для «Агрофермы»: Elasticsearch вместо ограничений стандартного поиска

Как мы настроили поиск по каталогу «Агрофермы»: приоритет собственного производства, обработка опечаток и неверной раскладки, фильтры и интеграция Elasticsearch с 1С-Битрикс. В статье — логика решения, пример PHP-кода и интерфейс поиска.

Содержание 6

Когда стандартного поиска 1С-Битрикс недостаточно

Стандартный поиск 1С-Битрикс подходит небольшим проектам без высокой нагрузки и специальных требований. Его можно быстро подключить, настроить поиск по полям и базовые правила выдачи.

В большом каталоге требования меняются: нужно обрабатывать сложные запросы, учитывать несколько полей и условия отбора, сохранять скорость при росте числа товаров. В описанном проекте возможностей стандартного решения для этих задач оказалось недостаточно. Ниже — ограничения, с которыми команда работала при выборе поискового движка.

  • Поисковые сценарии: требовались синонимы, обработка опечаток и расширенные фильтры.
  • Производительность: при большом объёме данных скорость зависела от настройки индекса и базы данных.
  • Ранжирование: базовых правил выдачи было недостаточно для нужных приоритетов товаров.
  • Настройка: проекту требовалось больше контроля над поведением поиска.

Почему выбрали Elasticsearch

Elasticsearch — распределённый поисковый и аналитический движок на основе Apache Lucene. Он объединяет индексацию, полнотекстовый поиск и агрегации данных.

Для каталога это даёт возможность строить сложные запросы, управлять релевантностью и распределять обработку данных между узлами. Такой подход позволяет развивать поиск по мере роста объёма информации и нагрузки.

Возможности движка в проекте

Для поискового сервиса важны три группы возможностей Elasticsearch: масштабирование, полнотекстовый поиск и работа с инструментами экосистемы Elastic.

  • Масштабирование и интеграция: данные и запросы можно распределять между узлами, а индексацию и поиск подключать к другим сервисам через API.
  • Поиск и аналитика: сложные запросы, автодополнение, поисковые подсказки, фасетный поиск и агрегации.
  • Экосистема Elastic: Logstash и Kibana дополняют работу с данными инструментами сбора и визуализации.

Два правила поиска для «Агрофермы»

Помимо выбора движка, мы настроили выдачу под задачи каталога.

  • Выше показываются товары из приоритетных для компании разделов, в том числе продукция собственного производства.
  • Поиск учитывает неверную раскладку клавиатуры: русский запрос, набранный английскими буквами, также может привести к нужному товару.
PHP
// Подготовка переменных:
// trim() удаляет лишние пробелы вокруг пользовательского запроса.
// mb_strtolower() преобразует пользовательский запрос в нижний регистр для выполнения нечувствительного к регистру сопоставления.
// mb_strtoupper() преобразует пользовательский запрос в верхний регистр для сопоставления с фразой с префиксом.

$query = trim ($_REQUEST['q']);
$fuzzy_query = mb_strtolower($query);
$match_phrase_prefix = mb_strtoupper($query);

// Проверка пустоты запроса:
// Если запрос пуст, скрипт завершается. 

if (empty($query)) {
	exit;
}

// Заменяет дефисы в пользовательском запросе на пробелы. Например, "some-query" станет "some query".

$query = str_replace('-', ' ', $query);


// Подготовка массива условий для выполнения поискового запроса в Elasticsearch:

$elastic_array = explode(' ', $query);

foreach ($elastic_array as $key => $word) {
	$elastic_array[$key] = '(*' . $word . '*)';
}

$elastic_query = implode(' AND ', $elastic_array);

// Подготовка настроек для нечеткого сопоставления:

// Создается ассоциативный массив $fuzzy_terms, содержащий параметры для нечеткого сопоставления в Elasticsearch. Значения параметров загружаются из JSON-строки.

$fuzzy_terms = json_decode('{
	"fuzziness": "AUTO",
	"max_expansions": 50,
	"prefix_length": 0,
	"transpositions": true,
	"rewrite": "constant_score"
  }', true);

// Подготовка основного запроса для Elasticsearch:
// Создается ассоциативный массив $array, который представляет основной запрос Elasticsearch. Значения параметров загружаются из JSON-строки.

$array = json_decode ('
{   
	"size": 6, 
    "sort": [
        {
            "is_own": {
                "order": "desc"
            }
        },
        {
            "hit": {
                "order": "desc"
            }
        },
        {
            "price": {
                "order": "desc"
            }
        }
    ],
    "query": {
   
        "fuzzy": {
        }
    }
}', true);

$array['query']['fuzzy']['first_word'] = $fuzzy_terms;
$array['query']['fuzzy']['first_word']['value'] = $fuzzy_query;
$result = get_elastic_result($array);

// Проверка результатов поиска:

if (empty($result['hits']['hits'])) {
	unset ($array['query']['fuzzy']['first_word']);
	$array['query']['fuzzy']['first_word_layout'] = $fuzzy_terms;
	$array['query']['fuzzy']['first_word_layout']['value'] = $fuzzy_query;
	$result = get_elastic_result($array);
}

// Проверка результатов повторного поиска:
// Если результаты повторного поиска также пусты, удаляются параметры для сопоставления фразы с префиксом.
// Вместо этого добавляются параметры для сопоставления всего запроса как единого индекса.
// Затем выполняется третий поиск Elasticsearch с обновленным запросом.

if (empty($result['hits']['hits'])) {

	unset ($array['query']['fuzzy']['first_word_layout']);
	$array['query']['fuzzy']['index'] = $fuzzy_terms;
	$array['query']['fuzzy']['index']['value'] = $fuzzy_query;
	$result = get_elastic_result($array);
}

// Затем выполняется третий поиск Elasticsearch с обновленным запросом.

Цитата сохранена из исходной статьи. В ней автор говорит о фильтрации тура; показатель 60 мс не относится к измерению товарного поиска «Агрофермы». По данным автора.

В данном проекте мы отказались от стандартного фильтра 1С-Битрикс и переписали все с нуля на Elasticsearch. Это позволило нам построить самый быстрый фильтр на рынке. Фильтрация тура происходит за 60 милисекунд. Это примерно в 5 раз быстрее, чем успеет моргнуть человек.

Сергей Буков
Сергей БуковРуководитель проекта

Что изменилось для каталога

По данным автора, на момент публикации каталог содержал более 10 000 уникальных товаров. Внедрение дало следующие возможности.

  • Поиск по каталогу более чем из 10 000 товаров с распределённой обработкой и отдельным поисковым индексом. По данным автора.
  • Настройка релевантности и приоритетов: подходящие запросу товары занимают первые позиции с учётом правил компании.
  • Интеграция с другими компонентами и возможность расширять поисковые сценарии без замены всего сайта.
  • Фильтры и агрегации для уточнения выдачи по категориям и другим параметрам.

Итог внедрения

На сайте «Агрофермы» появился поиск с управляемой выдачей, дополнительными фильтрами и обработкой ошибочного ввода. Автор связывает внедрение с улучшением производительности, удобства и конверсии; отдельные замеры конверсии в исходной статье не приведены.

Источники

Обсуждение

Задайте вопрос об этой работе, обсудите решение или поделитесь своим опытом.

Обсуждение открыто для всех участников.

Загружаем комментарии…