В этой статье мы рассмотрим, как расширить стандартный поиск в Битрикс, добавив возможность искать товары по артикулу прямо в компоненте bitrix:search.title. Это особенно полезно для интернет-магазинов, где покупатели часто ищут товары по артикулу производителя.
Варианты реализации
Существует два основных подхода:
-
Точный поиск – когда система ищет товары только по полному совпадению артикула.
-
Поиск по части артикула – когда можно найти товары, даже если введена только часть кода.
Мы рассмотрим оба варианта, а также оптимизированные решения для больших каталогов.
1. Подготовка шаблона компонента
Шаг 1: Локализация файлов компонента
Компонент search.title обычно находится в папке:
/bitrix/components/bitrix/search.title/Но для кастомизации лучше скопировать его в свой шаблон:
/local/templates/[ваш_шаблон]/components/bitrix/search.title/[ваша_реализация]/Шаг 2: Модификация result_modifier.php
Добавим логику поиска по артикулу.
Базовый вариант (точный поиск)
if (!empty($arResult['query'])) {
$articleCode = 'PROPERTY_CML2_ARTICLE'; // Замените на свой код свойства
$iBlockId = 33; // Замените на ID инфоблока
$filter = [
'IBLOCK_ID' => $iBlockId,
'ACTIVE' => 'Y',
$articleCode => $arResult['query']
];
$elements = CIBlockElement::GetList(
[],
$filter,
false,
false,
['ID', 'NAME', 'DETAIL_PAGE_URL', 'PROPERTY_CML2_ARTICLE']
);
while ($element = $elements->GetNext()) {
$arResult['FOUND_ITEMS'][] = $element;
}
}Расширенный вариант (поиск по части артикула)
if (!empty($arResult['query'])) {
$articleCode = 'PROPERTY_CML2_ARTICLE';
$iBlockId = 33;
$filter = [
'IBLOCK_ID' => $iBlockId,
'ACTIVE' => 'Y',
$articleCode . '%' => $arResult['query'] // Ищем по части артикула
];
// Остальной код аналогичен
}2. Вывод результатов в ajax.php
Теперь модифицируем вывод, чтобы найденные товары отображались в выпадающем списке.
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();?>
<?if (!empty($arResult['FOUND_ITEMS'])):?>
<div class="search-results">
<?foreach ($arResult['FOUND_ITEMS'] as $item):?>
<a href="<?=$item['DETAIL_PAGE_URL']?>" class="search-result-item">
<span class="item-name"><?=$item['NAME']?></span>
<span class="item-article">Артикул: <?=$item['PROPERTY_CML2_ARTICLE_VALUE']?></span>
</a>
<?endforeach;?>
</div>
<?endif;?>3. Оптимизация для больших каталогов
Если в вашем магазине тысячи товаров, стандартный поиск может работать медленно. Вот несколько улучшений:
1. Использование индексации
Добавьте индекс для свойства с артикулом в базе данных:
CREATE INDEX ix_article_property ON b_iblock_element_property (VALUE) WHERE IBLOCK_PROPERTY_ID = [ID_свойства];2. Кеширование результатов
$cache = Bitrix\Main\Data\Cache::createInstance();
$cacheId = 'search_article_' . md5($arResult['query']);
$cacheTime = 3600; // 1 час
if ($cache->initCache($cacheTime, $cacheId, '/search_article/')) {
$arResult = $cache->getVars();
} elseif ($cache->startDataCache()) {
// Здесь выполняем поиск
$cache->endDataCache($arResult);
}3. Использование Sphinx или ElasticSearch
Для очень больших магазинов лучше подключить полнотекстовый поиск:
$search = new \Bitrix\Search\Search();
$result = $search->query($arResult['query'], 'iblock_' . $iBlockId);4. Дополнительные улучшения
Поддержка нескольких инфоблоков
$iBlocks = [33, 34]; // ID инфоблоков
$filter['IBLOCK_ID'] = $iBlocks;AJAX-подгрузка при вводе
BX.ready(function() {
BX.bind(BX('search-input'), 'input', function() {
BX.ajax({
url: '/ajax/search.php',
data: { q: this.value },
onsuccess: function(data) {
BX('search-results').innerHTML = data;
}
});
});
});Заключение
Мы рассмотрели:
-
Базовую настройку поиска по артикулу.
-
Оптимизацию для больших каталогов.
-
Дополнительные улучшения, такие как кеширование и AJAX.
Это решение значительно ускорит поиск товаров и улучшит пользовательский опыт.