Перейти к содержимому

Количество товаров в фильтре - фасетный индекс и пустые значения

Разбираемся, откуда в умном фильтре берутся числа рядом со значениями и почему они расходятся с тем, что реально лежит в разделе.

Решение

Помечаем фасетный индекс на пересборку:

use Bitrix\Iblock\PropertyIndex;
// состояние индекса видно в админке: Настройки - Инфоблоки - Фасетные индексы
// из кода индекс помечают невалидным, чтобы каталог пересобрал его заново
PropertyIndex\Manager::markAsInvalid(5);
// цифра 5 здесь - идентификатор инфоблока каталога на этом сайте
// без индекса количества не считаются вовсе, а фильтр работает перебором

Числа рядом со значениями берутся из отдельной таблицы, а не из каталога напрямую. Эта таблица и есть фасетный индекс: он хранит готовые связки «значение свойства - раздел - число товаров».

Запускаем построение индекса:

$storage = new \Bitrix\Iblock\PropertyIndex\Storage(5);
$storage->dropIndex(); // старая таблица удаляется целиком
$storage->initIndex();
$indexer = new \Bitrix\Iblock\PropertyIndex\Indexer(5);
$indexer->startIndex(); // на большом каталоге идёт минутами
// пока идёт построение, фильтр показывает неполные числа

Построение читает весь каталог, поэтому на десятках тысяч позиций оно занимает минуты. Запускать его в час пик не стоит: пока таблица пересобирается, фильтр показывает неполные числа.

Включаем показ количеств и скрытие пустых значений:

$APPLICATION->IncludeComponent('bitrix:catalog.smart.filter', '', [
'IBLOCK_ID' => 5,
'SECTION_ID' => $sectionId,
'FILTER_NAME' => 'arrFilter',
'HIDE_NOT_AVAILABLE' => 'Y', // прячет значения без доступных товаров
]);

Скрытие пустых значений работает только при живом индексе. Без него компонент не знает, есть ли за значением товары, и показывает весь справочник свойства целиком.

Проверяем расхождение числа и выдачи:

$count = CIBlockElement::GetList([], ['IBLOCK_ID' => 5, 'SECTION_ID' => $sectionId,
'INCLUDE_SUBSECTIONS' => 'Y', 'ACTIVE' => 'Y', 'PROPERTY_COLOR' => 12], []);
printf("в каталоге=%d\n", $count);
// расхождение с числом в фильтре означает устаревший индекс

Число в фильтре и число в выдаче считаются из разных источников. Расхождение означает не ошибку компонента, а устаревший индекс, и лечится оно его перестроением, а не правкой шаблона.

Индекс пересобирается при правке товара, но не при массовой загрузке. Обмен с учётной системой меняет тысячи позиций мимо обычного сохранения, поэтому его завершение стоит связывать с постановкой пересчёта в очередь.

Индекс строится по каждому инфоблоку отдельно, включая инфоблок предложений. Каталог с торговыми предложениями требует построения для обоих, иначе фильтр по свойствам предложений считает числа неверно.

Свойства с сотнями значений замедляют и индекс, и сам фильтр. Такие свойства либо выносят из фильтрации, либо превращают в диапазоны: справочник на тысячу строк бесполезен покупателю и дорог платформе.

Типичные проблемы

Рядом со значениями нет чисел.

Фасетный индекс не построен для этого инфоблока каталога. Числа рядом со значениями берутся только из него, а не из каталога напрямую.

Числа не совпадают с выдачей.

Индекс устарел после массовой правки товаров каталога. Обмен и импорт меняют позиции мимо обычного сохранения элемента.

В фильтре висят значения без товаров.

Выключено скрытие недоступных значений либо не построен сам индекс. Без индекса компонент показывает весь справочник свойства целиком.

Фильтр открывается по десять секунд.

Индекса нет, и условия фильтра проверяются перебором свойств. Каждое свойство при этом добавляет к запросу отдельное соединение таблиц.

После обмена фильтр показывает старые бренды.

Пересчёт индекса не поставлен в очередь после обмена данными. Сам по завершении загрузки данных он не запускается.

Частые вопросы

Обязателен ли индекс для работы фильтра?

Нет, фильтр работает и без него, но медленно и без чисел. На каталоге в тысячи позиций разница видна сразу.

Как пересчитывать индекс автоматически?

Постановкой задачи после обмена: платформа умеет достраивать индекс порциями. Полное построение вручную нужно только после смены состава свойств.

Почему числа считаются с учётом подразделов?

Индекс хранит связку значения с разделом и его ветвью. Товар из подраздела попадает в число родительского раздела.

Можно ли показывать значения без товаров?

Да, скрытие отключается параметром компонента. Такие значения полезны в узких каталогах, где выбор важнее чистоты списка.

Смежное

Первоисточник