Поиск по сайту теряет названия после обновления search 26.0.0
Проблема/контекст
После обновления модуля search до 26.0.0 и полной переиндексации страница поиска перестаёт находить товары и страницы по словам из названия. На демо-магазине из готового решения «Интернет-магазин» («Управление сайтом», search 26.100.0) подсказка в шапке по слову «валькирии» показывает «Туфли Полет Валькирии», а search.page отвечает «ничего не найдено». Страница «Склады» по слову «склады» тоже не находится, в выдаче только «О магазине», где это слово есть в тексте страницы.

Решение с кодом
Ошибка в CSearch::Index(), в коде, который добавляет в индекс новую запись. До 26.0.0 заголовок попадал в текст для поиска всегда, кроме случая, когда модуль передал INDEX_TITLE => false. В 26.0.0 условие стало таким:
// search 26.0.0, classes/general/search.php
if (
!isset($arFields['INDEX_TITLE'])
|| (
array_key_exists('INDEX_TITLE', $arFields)
&& $arFields['INDEX_TITLE'] === false
)
)
{
$content = '';
}
Теперь заголовок пропускается и тогда, когда ключа нет вообще. Из модулей ядра INDEX_TITLE передают только forum (true для первого сообщения темы) и blog (false для комментариев). Инфоблоки, статические страницы, записи блога и остальные модули ключ не передают, и их новые записи попадают в индекс без названия.
Текст для поиска хранится в поле SEARCHABLE_CONTENT. По нему модуль строит свой индекс по основам слов или FULLTEXT-индекс в MySQL и PostgreSQL, и по нему ищет search.page. Подсказку search.title ошибка не задевает: у неё своя таблица b_search_content_title, и CSearch::IndexTitle() заполняет её при любом значении ключа, кроме false. Sphinx и OpenSearch получают заголовок отдельным полем.
Если запись в индексе уже есть, Index() обновляет её другим кодом, и там заголовок по-прежнему добавляется. Поэтому сразу после обновления модуля поиск работает. Пересохранённый товар находится, а только что созданный уже нет. Полная переиндексация очищает индекс и добавляет все записи заново, после неё названия теряет весь сайт. В 26.100.0 ошибку не исправили.
Пока исправления нет, добавьте в /local/php_interface/init.php обработчик события search:BeforeIndex. CSearch::Index() вызывает событие до записи и дальше работает с массивом, который вернул обработчик:
<?php
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'search',
'BeforeIndex',
static function (array $fields): array {
// forum и blog передают ключ сами, их значение не трогаем
if (!array_key_exists('INDEX_TITLE', $fields)) {
$fields['INDEX_TITLE'] = true;
}
return $fields;
}
);
Ключ INDEX_TITLE влияет только на добавление новых записей. Обновление существующих записей и подсказка search.title работают с true так же, как без ключа, поэтому там обработчик ничего не меняет.
После добавления обработчика запустите «Настройки → Поиск → Переиндексация» со снятой галочкой «Переиндексировать только измененные». С галочкой переиндексация обновит только товары и страницы, изменённые после прошлой индексации, а остальные останутся в индексе без названий. На демо-магазине после полной переиндексации с обработчиком туфли находятся по слову «валькирии», а «Склады» стоят первыми в выдаче по слову «склады».

Итог
Проверить свой сайт можно за минуту. Возьмите товар, в названии которого есть слово, которого нет в описании, например «валькирии» у «Туфли Полет Валькирии», и введите это слово в поиск. Если подсказка в шапке товар показывает, а страница поиска пишет «ничего не найдено», ошибка есть: добавьте обработчик и запустите полную переиндексацию.