Search 26.0.0–26.100.0: новые атрибуты Sphinx, переиндексация из консоли и исправленная проверка прав
Ломающее обновление
Удалены или изменены публичные API — прикладной код может перестать работать.
Модуль поиска обновился сразу на две версии: 25.200.0 → 26.0.0 → 26.100.0. Без правки sphinx.conf индексация на Sphinx перестанет работать, а у встроенного движка и FULLTEXT MySQL/PostgreSQL, судя по коду, заголовки новых записей больше не попадают в индексируемый текст. В 26.100.0 закрыли пропуск проверки прав в одной из веток SQL-поиска, так что обновляться стоит, но сначала на стенде и с проверкой поиска.
Новое
Переиндексируйте из консоли (26.0.0)
Появилась команда search:reindex. Большой сайт теперь можно переиндексировать без браузера и без таймаутов веб-сервера:
php bitrix/bitrix.php search:reindex --full --step-duration=20
# если процесс прервался, продолжаем с того же места
php bitrix/bitrix.php search:reindex --full --continue
Есть ещё --site, --module, --clear-suggest и --trace, последняя печатает выполненные SQL. Состояние для --continue хранится в персистентном хранилище ядра сутки.
Меняйте права в индексе одним запросом (26.0.0)
CSearch::AddPermission() и CSearch::DeletePermission() добавляют или снимают код группы у всех записей индекса, подходящих под фильтр. Модуль переиндексировать не нужно:
<?php declare(strict_types=1);
use Bitrix\Main\Loader;
Loader::includeModule('search');
// открыть группе 5 найденные элементы инфоблока 12, потом закрыть
\CSearch::AddPermission('iblock', 'G5', ['PARAM2' => 12]);
\CSearch::DeletePermission('iblock', 'G5', ['PARAM2' => 12]);
Внутри это один INSERT IGNORE ... SELECT или один DELETE. В OpenSearch и Sphinx права догоняет очередь Messenger search_sync_perm. Заодно DeleteIndex() вторым аргументом принимает массив-фильтр, а фильтр поиска понимает USER_ID, ENTITY_TYPE_ID и ENTITY_ID.
Подключите нейропоиск OpenSearch (26.0.0)
Если задать модель, шаблон индекса получает поле body_ml типа knn_vector, а поиск вместо match строит запрос neural с k = 10:
<?php declare(strict_types=1);
use Bitrix\Main\Config\Option;
Option::set('search', 'opensearch_index_model_id', 'id-модели-в-opensearch');
Option::set('search', 'opensearch_index_dimension', '768'); // размерность вашей модели
Option::set('search', 'opensearch_index_space_type', 'l2');
В админке этих опций нет. Модель и ingest-pipeline с именем <индекс>-pipeline нужно создать в OpenSearch самостоятельно, модуль только ссылается на них. Версия шаблона индекса выросла с 27 до 28. Шаблон модуль пересоздаст сам, но уже созданные индексы получат новую схему только после полной переиндексации, даже если модель не задана. Индекс и модель модуль сначала ищет в CPageOption, их можно подменить на один хит.
Отложите индексацию, пока OpenSearch лежит (26.100.0)
Опция full_text_delay_index (по умолчанию N, работает только с OpenSearch) складывает изменения индекса в очередь search_sync_content, откуда их забирает обработчик. Если сервер недоступен, сообщение повторится через минуту. В настройках модуля написано, что включать её стоит только на время недоступности сервера. Админская переиндексация и search:reindex её на своём хите выключают.
Что сломается
Добавьте пять атрибутов в sphinx.conf (26.0.0)
RT-индекс Sphinx должен содержать новые атрибуты. Без них проверка в настройках модуля выдаст ошибку, а CSearchSphinx::replace() будет бросать SqlQueryException при записи в индекс:
rt_attr_uint = user_id
rt_attr_string = entity_type
rt_attr_uint = entity_type_id
rt_attr_string = entity
rt_attr_uint = entity_id
После правки индекс придётся пересоздать и переиндексировать сайт.
Проверьте поиск по названиям (26.0.0)
В коде 26.0.0 при вставке новой записи CSearch::Index() больше не кладёт заголовок в SEARCHABLE_CONTENT, если в полях нет ключа INDEX_TITLE. Раньше заголовок шёл в начало контента. При обновлении существующей записи он по-прежнему добавляется. INDEX_TITLE передают только blog (в комментариях, всегда false) и forum (true только у первого сообщения темы), у них ничего не меняется. Инфоблоки, страницы сайта и остальные модули ключ не передают.
По коду выходит, что после полной переиндексации все записи проходят через вставку, и слова, которые есть только в названии, перестанут находиться через bitrix:search.page на встроенном движке и на FULLTEXT MySQL и PostgreSQL. search.title это не затрагивает, OpenSearch и Sphinx тоже: они собирают заголовок сами. В 26.100.0 код не поменялся. Проверьте на стенде, находится ли элемент по слову, которое есть только в его названии.
Не ждите обновления URL в индексе (26.0.0)
CSearch::UpdateSite() перестал переписывать URL, если запись для этого сайта уже есть. Модули, которые передают SITE_ID в виде [сайт => адрес], после смены адреса будут показывать в выдаче старую ссылку до полной переиндексации.
Передавайте настройки движка в конструктор (26.100.0)
connect() полнотекстовых движков теперь принимает только $ignoreErrors, а адрес, индекс и учётные данные переехали в конструктор. getInstance() больше не подключается сам, соединение открывает первый запрос. Своя проверка соединения теперь выглядит так:
<?php declare(strict_types=1);
use Bitrix\Main\Loader;
Loader::includeModule('search');
$engine = new \CSearchOpenSearch([
'connection' => 'https://opensearch.local:9200',
'user' => 'bitrix',
'password' => getenv('OPENSEARCH_PASSWORD') ?: '',
'index_name' => 'bitrix',
]);
if (!$engine->connect(true)) {
// причина лежит в $APPLICATION->GetException()
}
Для Sphinx то же самое: new \CSearchSphinx(['connection' => ..., 'index_name' => ...]). Кроме того, CSearchOpenSearch::query() на любой ошибочный ответ, включая 404, теперь бросает \Bitrix\Main\DB\ConnectionException. Раньше метод возвращал false; код, который на это рассчитывает, теперь получит исключение.
Уберите обращения к удалённому и скрытому (26.0.0)
- Удалён
CAllSearch::QueryMnogoSearch(), запрос к mnogosearch.org черезfsockopen. - Свойства
CSearchTitle::$_arPhrase,$_arStemFunc,$minLengthиCSearchStatistic::$_phrase,$_tags,$_session_id,$_stat_sess_idстали protected, обращение снаружи дастError. __PrepareFilter()сам разбираетUSER_ID,ENTITY_TYPE_IDиENTITY_ID, и для этих ключей ваш обработчикOnSearchPrepareFilterбольше не вызывается.
Мелочи и находки
- В 26.100.0 закрыт пропуск проверки прав. Одна из веток
CSearch::MakeSQL(), без сайта и без стемминга, собирала условие безCSearch::CheckPermissions(). Теперь проверка на месте.bitrix:search.pageвсегда передаёт сайт и через эту ветку не ходил. - В 26.100.0 подсветка найденного слова в UTF-8 больше не съезжает,
GetContentItemParams()возвращает все значения многозначного параметра, а обработчикOnAfterIndexAddвызывается после записи прав, сайтов и параметров и видит их в таблицах. - Немецкий язык с 26.0.0 получил стемминг, стоп-слова и класс языка с раскладкой QWERTZ.
- В
options.phpс 26.0.0 вызываетсяGetMessage('EARCH_OPTIONS_FULL_REINDEX')без первой буквы, и после смены полнотекстового движка уведомление о переиндексации не появляется вовсе:CAdminNotify::Add()отбрасывает пустой текст. В 26.100.0 опечатку не поправили.
Устаревшие и удалённые API в этой версии
| Символ | Статус | Чем заменять |
|---|---|---|
CAllSearch::QueryMnogoSearch()
|
Удалено | — |