Живой поиск с подсказками - выдача, доступность, подстроки
Делаем подсказки в поиске по сайту: компонент, чистая выдача, поиск по части слова и своевременная переиндексация.
Решение
Ставим компонент подсказок:
$APPLICATION->IncludeComponent('bitrix:search.title', '', [ 'CATEGORY_0' => ['iblock_catalog'], // где искать: тип инфоблока 'CATEGORY_0_iblock_catalog' => [$iblockId], // и конкретный инфоблок 'SHOW_INPUT' => 'Y', 'TOP_COUNT' => 5, 'CHECK_DATES' => 'Y', // снятое с публикации не показывать]);Категории поиска ограничивают выдачу нужным разделом. Без них подсказки приносят новости, служебные страницы и элементы соседних инфоблоков, и покупатель видит случайный набор ссылок вместо товаров.
Убираем недоступные товары из индекса:
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler('search', 'BeforeIndex', static function ($fields) { // массив приходит по значению if ($fields['MODULE_ID'] === 'iblock' && !isAvailable($fields['ITEM_ID'])) { unset($fields['BODY']); // так запись исключается из индекса } return $fields; // обработчик обязан вернуть массив });Компонент подсказок не проверяет доступность товара сам. Он показывает то, что лежит в индексе, поэтому товары без цены и снятые с продажи убирают на этапе индексации, а не в шаблоне выдачи.
Обработчик принимает массив по значению и обязан его вернуть. Ссылка в сигнатуре здесь ошибка: правки уедут в никуда, а элемент попадёт в индекс без изменений.
Обработчик индексации - единственное место, где такую чистку делают дёшево. Правка шаблона выдачи не помогает: компонент уже посчитал количество найденного, и страница «показать всё» останется пустой при непустых подсказках.
Добавляем свои поисковые фразы:
$prop = new CIBlockProperty();$prop->Add(['IBLOCK_ID' => $iblockId, 'CODE' => 'SEARCH_WORDS', 'NAME' => 'Поисковые фразы', 'PROPERTY_TYPE' => 'S', 'SEARCHABLE' => 'Y']); // значения свойства участвуют в поиске// в свойство кладут синонимы и обиходные названия: «термокольцо», «кольцо»Подсказки ищут только по заголовкам элементов, и это не настраивается. Полный поиск по описаниям и свойствам делает страница результатов, а подсказки остаются быстрым поиском по названиям.
Второе ограничение - поиск по началу слова, а не по любой его части. Запрос «ильник» не найдёт светильник никогда, и лечится это списком синонимов в отдельном свойстве или внешним поисковым движком.
Синонимы в свойстве решают и вторую задачу - народные названия. Покупатель ищет «зарядку» вместо «блока питания», и список таких слов в отдельном поле работает лучше любой настройки морфологии.
Пересобираем индекс после массовых правок:
\Bitrix\Main\Loader::includeModule('search');CSearch::ReIndexAll(false, 30); // порциями по 30 секунд, чтобы не упереться в предел// при обычном сохранении элемента индекс обновляется сам, при массовой правке - нетДелаем подсказки по своим данным без модуля поиска:
$rs = CIBlockElement::GetList(['SORT' => 'ASC'], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y', '%NAME' => $query], false, ['nTopCount' => 10], ['ID', 'NAME', 'DETAIL_PAGE_URL']);// поиск по части названия: медленнее индекса, но ищет по середине слова// такой ответ отдают своим ajax-действием, а не отдельным файлом в корнеСвой поиск по названию оправдан там, где элементов немного и нужна именно подстрока. На каталоге в десятки тысяч позиций он проигрывает индексу по скорости, и тогда возвращаются к модулю поиска с синонимами.
Типичные проблемы
В подсказках появляются неактивные товары и товары без цены.
Компонент подсказок не проверяет доступность и показывает содержимое индекса. Недоступные записи убирают обработчиком события прямо на этапе их попадания в индекс.
Поиск по части слова ничего не находит.
Подсказки ищут по началу слова и только по заголовкам элементов. Синонимы кладут в отдельное свойство инфоблока либо ставят внешний поисковый движок целиком.
После обмена подсказки показывают старые названия.
Массовая запись элементов не обновляет индекс поиска сама по себе, в отличие от ручного сохранения. После крупных правок и обмена с учётной системой запускают полную переиндексацию.
В подсказках попадаются служебные страницы.
Категории поиска в параметрах компонента не ограничены нужным инфоблоком каталога товаров сайта. Область поиска задают параметрами компонента, а не фильтрацией в шаблоне выдачи.
Запрос подсказок отвечает ошибкой пятисотой.
Шаблон подсказок переверстан или его обработчик правился под другую версию самого продукта. Ошибку в этом случае ищут в журнале сервера, а не в настройках компонента.
Частые вопросы
Почему подсказки показывают недоступные товары?
Компонент отдаёт содержимое поискового индекса и доступность не проверяет - это его известное поведение. Недоступные позиции исключают из индекса обработчиком события индексации.
Как научить поиск находить по середине слова?
Штатный индекс так не умеет: он ищет по началу слова, а подсказки - ещё и только по заголовкам. Обычно заводят свойство с синонимами и обиходными названиями, а при серьёзных требованиях ставят внешний поисковый движок.
Когда нужна переиндексация?
После массовых правок, обмена с учётной системой и изменения списка индексируемых свойств. При обычном сохранении элемента в админке индекс обновляется сам.
Делать подсказки своим кодом или компонентом?
Компонентом, если поиск идёт по каталогу и нужен нормальный индекс. Своим ajax-действием - если данных немного и требуется поиск по произвольной подстроке.
Почему в подсказках нет части товаров?
Либо они не попали в индекс, либо их отсекли категории поиска в параметрах компонента. Проверяют оба условия: сначала наличие записи в индексе, потом настройки области поиска.
Смежное
- Релевантность выдачи: правила сортировки, стоп-слова, вес - цена быстрого поиска для ранжирования
- Поиск по сайту - оглавление подтемы
- Настройка поиска по сайту: индексация, области, права - как устроен сам индекс
- Поиск не находит товары: индекс, переиндексация, выдача - разбор пустой выдачи
- Теги и облако тегов: включение, ввод, вывод, поиск по тегу - другой способ навигации по индексу
- Внешний поисковый движок: подключение, индекс, отказоустойчивость - когда штатного индекса мало
- AJAX-запрос: контроллер, действия, ответ - как отдавать свои подсказки
- Модули и решения - устройство модулей целиком