Дата последнего изменения: 08.10.2024
Компонент Умный фильтр доступен в продукте, начиная с версии 12.0 модуля Информационные блоки. При всех своих достоинствах он обладал существенным недостатком — в каталогах больших размеров фильтрация элементов занимала продолжительное время. Для решения этой проблемы в версии 15.0 была добавлена технология фасетного поиска.
При разработке фасетного индекса упор был сделан на максимальное использование возможностей нового ядра. Взаимодействие с другим кодом происходит с помощью 3-х методов специального класса:
Use \Bitrix\Iblock\PropertyIndex; PropertyIndex\Manager::updateElementIndex($iblockId, $elementId); PropertyIndex\Manager::deleteElementIndex($iblockId, $elementId); PropertyIndex\Manager::markAsInvalid($iblockId);
В базе данных индекс представляет собой пару таблиц. Одна из них - это словарь для значений строковых свойств, а вторая - денормализованная карта значений элемента и его привязок к разделам.
CRE ATE TABLE b_iblock_X_index ( SECTION_ID INT NOT NULL, ELEMENT_ID INT NOT NULL, FACET_ID INT NOT NULL, VALUE INT NOT NULL, VALUE_NUM FLOAT NOT NULL, INCLUDE_SUBSECTIONS VARCHAR(1) NOT NULL, KEY IX_b_iblock_X_index_0 (SECTION_ID,ELEMENT_ID,FACET_ID, VALUE_NUM, VALUE, ELEMENT_ID), KEY IX_b_iblock_X_index_1 (ELEMENT_ID, SECTION_ID, FACET_ID) ); CRE ATE TABLE b_iblock_X_index_val ( ID INT NOT NULL AUTO_INCREMENT, VALUE VARCHAR(2000), PRIMARY KEY (ID) );
Рассмотрим детальнее первую таблицу. Для этого в административном разделе сайта перейдите на страницу Настройки > Производительность > Таблицы и выберите таблицу b_iblock_X_index (где Х - идентификатор вашего каталога). Данные рассмотрим на примере конкретного элемента каталога (в нашем случае для элемента с идентификатором 36):
По колонке SECTION_ID можно видеть, что данные сохранены не только для раздела элемента (в колонке INCLUDE_SUBSECTIONS стоит 1), но и всех его родителей (в колонке INCLUDE_SUBSECTIONS стоит 0).
FACET_ID - это синтетический идентификатор цен и свойств. Для цен используются нечётные идентификаторы (идентификатор цены умножается на 2 и прибавляется 1), а для свойств - четные (идентификатор свойства умножается на 2). Именно этот прием позволяет строить комбинированные фильтры по цене и значениям свойств.
Производительность умного фильтра на каталоге среднего размера.
Рассмотрим работу умного фильтра на каталоге среднего размера: 20 тысяч товаров, 60 тысяч предложений и 780 тысяч значений свойств. Таким образом, каталог с товарами имеет следующие характеристики:
После того, как для каталога будут созданы фасетные индексы, таблица b_iblock_X_index будет содержать 520 тыс. записей, данные будут занимать 12 Мбайт, индексы - 30 Мб, средняя длина строки - 24 байта.
На следующей диаграмме представлено время работы компонента умного фильтра без фильтрации на одном из корневых разделов каталога с 10 тысячами элементов, подразделе с 3 тысячами товаров и подразделе подраздела со 100 товарами:
Столь впечатляющих результатов при использовании индекса удалось добиться за счет того, что работа по выборке данных, их группировке и анализу большей частью проводится в момент индексации.
Если посмотреть показатели с установленным фильтром по цене, то видим, что использование фасетного индекса также эффективно:
Хорошие показатели наблюдаются и при различных вариантах фильтрации каталога по цене и свойствам (например, по свойству Цвет):
Кроме того, использование фасетных индексов позволяет снизить и стабилизировать расход памяти PHP:
Это связано с тем, что вся работа по группировке товаров ложится на базу данных. Часть работы выполняется на этапе индексации, а часть - при выборке, опираясь на мощную поддержку в виде фасетного индекса. Поэтому на долю PHP остается малая часть, которая выполняется быстро и эффективно.
Фасетные индексы могут пересоздаваться автоматически или требовать ручного пересоздания в зависимости от выполненных действий:
|
Обновить фасетный индекс при помощи API можно методом updateElementIndex:
\Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex($arIBlock["ID"], $ID);