Компонент search.title в 1С-Битрикс не поддерживает сложную фильтрацию "из коробки". Это создает проблемы, когда нужно:
-
Скрыть товары с нулевым остатком (
CATALOG_QUANTITY <= 0) -
Исключить элементы с определенными свойствами (например,
NE_VYGRUZHAT_NA_SAYT = true) -
Добавить кастомные условия вывода в поисковой выдаче
Рассмотрим 3 рабочих метода решения этой задачи с анализом их плюсов и минусов.
Метод 1: Прямая модификация ajax.php (простое, но не идеальное решение)
Код реализации
<?php
if (CModule::IncludeModule("iblock")) {
$element = CIBlockElement::GetList(
["ID" => "ASC"],
[
"IBLOCK_ID" => $IBLOCK_ID,
"ACTIVE" => "Y",
"ID" => $arItem['ITEM_ID'],
">CATALOG_QUANTITY" => 0, // Только товары с остатком
"!PROPERTY_NE_VYGRUZHAT_NA_SAYT_VALUE" => false // Исключаем скрытые
],
false,
false,
["ID"] // Оптимизация: запрашиваем только ID
);
if (!$element->Fetch()) {
continue; // Пропускаем товар
}
}
?>Плюсы и минусы
| Преимущества | Недостатки |
|---|---|
| Просто внедрить | Прямое редактирование компонента (риск при обновлениях) |
| Работает без переделки архитектуры | Дополнительные SQL-запросы замедляют поиск |
| Подходит для быстрых правок | Нет кеширования |
Когда использовать: Срочные правки на небольших сайтах.
Метод 2: Обработчик события OnSearchGetURL (рекомендуемый способ)
Более правильный подход через API Битрикс.
Код реализации
AddEventHandler("search", "OnSearchGetURL", "filterSearchResults");
function filterSearchResults($arFields) {
if (CModule::IncludeModule("iblock")) {
$element = CIBlockElement::GetByID($arFields["ITEM_ID"])->Fetch();
if (
$element["PROPERTY_NE_VYGRUZHAT_NA_SAYT_VALUE"] ||
$element["CATALOG_QUANTITY"] <= 0
) {
return false; // Исключаем из результатов
}
}
return $arFields;
}Плюсы и минусы
| Преимущества | Недостатки |
|---|---|
| Не требует правки компонентов | Требует понимания работы событий |
| Работает на уровне ядра поиска | Нужно аккуратно тестировать |
| Легко масштабируется |
Когда использовать: Для долгосрочных проектов.
Метод 3: Оптимизированный вариант с кешированием
Улучшаем производительность за счет кеширования.
Код реализации
AddEventHandler("search", "OnSearchGetURL", "filterSearchResultsWithCache");
function filterSearchResultsWithCache($arFields) {
$cache = new CPHPCache();
$cacheTime = 3600; // 1 час
$cacheID = "search_filter_" . $arFields["ITEM_ID"];
if ($cache->InitCache($cacheTime, $cacheID)) {
$cachedData = $cache->GetVars();
if ($cachedData["is_hidden"]) return false;
} else {
if (CModule::IncludeModule("iblock")) {
$element = CIBlockElement::GetByID($arFields["ITEM_ID"])->Fetch();
$isHidden = (
$element["PROPERTY_NE_VYGRUZHAT_NA_SAYT_VALUE"] ||
$element["CATALOG_QUANTITY"] <= 0
);
$cache->StartDataCache();
$cache->EndDataCache(["is_hidden" => $isHidden]);
if ($isHidden) return false;
}
}
return $arFields;
}Плюсы и минусы
| Преимущества | Недостатки |
|---|---|
| Максимальная производительность | Сложнее в реализации |
| Уменьшение нагрузки на БД | Требует настройки кеша |
| Подходит для высоконагруженных сайтов |
Когда использовать: Для сайтов с большим количеством поисковых запросов.
Итоговая сравнительная таблица методов
| Критерий | Правка ajax.php | OnSearchGetURL | Кеширование |
|---|---|---|---|
| Сложность | Низкая | Средняя | Высокая |
| Безопасность | Низкая (риск при обновлениях) | Высокая | Высокая |
| Производительность | Низкая (много запросов) | Средняя | Высокая |
| Гибкость | Ограниченная | Высокая | Очень высокая |
| Рекомендация | Только для временных решений | Основной рабочий вариант | Для высоконагруженных проектов |
Полезные ссылки
Заключение
-
Для быстрого решения Метод 1 (правка ajax.php)
-
Для надежного долгосрочного проекта Метод 2 (OnSearchGetURL)
-
Для высоконагруженных сайтов Метод 3 (кеширование)