Количество товаров в фильтре - фасетный индекс и пустые значения
Разбираемся, откуда в умном фильтре берутся числа рядом со значениями и почему они расходятся с тем, что реально лежит в разделе.
Решение
Помечаем фасетный индекс на пересборку:
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);// расхождение с числом в фильтре означает устаревший индексЧисло в фильтре и число в выдаче считаются из разных источников. Расхождение означает не ошибку компонента, а устаревший индекс, и лечится оно его перестроением, а не правкой шаблона.
Индекс пересобирается при правке товара, но не при массовой загрузке. Обмен с учётной системой меняет тысячи позиций мимо обычного сохранения, поэтому его завершение стоит связывать с постановкой пересчёта в очередь.
Индекс строится по каждому инфоблоку отдельно, включая инфоблок предложений. Каталог с торговыми предложениями требует построения для обоих, иначе фильтр по свойствам предложений считает числа неверно.
Свойства с сотнями значений замедляют и индекс, и сам фильтр. Такие свойства либо выносят из фильтрации, либо превращают в диапазоны: справочник на тысячу строк бесполезен покупателю и дорог платформе.
Типичные проблемы
Рядом со значениями нет чисел.
Фасетный индекс не построен для этого инфоблока каталога. Числа рядом со значениями берутся только из него, а не из каталога напрямую.
Числа не совпадают с выдачей.
Индекс устарел после массовой правки товаров каталога. Обмен и импорт меняют позиции мимо обычного сохранения элемента.
В фильтре висят значения без товаров.
Выключено скрытие недоступных значений либо не построен сам индекс. Без индекса компонент показывает весь справочник свойства целиком.
Фильтр открывается по десять секунд.
Индекса нет, и условия фильтра проверяются перебором свойств. Каждое свойство при этом добавляет к запросу отдельное соединение таблиц.
После обмена фильтр показывает старые бренды.
Пересчёт индекса не поставлен в очередь после обмена данными. Сам по завершении загрузки данных он не запускается.
Частые вопросы
Обязателен ли индекс для работы фильтра?
Нет, фильтр работает и без него, но медленно и без чисел. На каталоге в тысячи позиций разница видна сразу.
Как пересчитывать индекс автоматически?
Постановкой задачи после обмена: платформа умеет достраивать индекс порциями. Полное построение вручную нужно только после смены состава свойств.
Почему числа считаются с учётом подразделов?
Индекс хранит связку значения с разделом и его ветвью. Товар из подраздела попадает в число родительского раздела.
Можно ли показывать значения без товаров?
Да, скрытие отключается параметром компонента. Такие значения полезны в узких каталогах, где выбор важнее чистоты списка.
Смежное
-
Фильтр по цене и наличию: диапазон, валюта, склад - границы диапазона и устаревший индекс
-
Умный фильтр - оглавление подтемы
-
Умный фильтр: настройка, свойства и адреса фильтрации - настройка фильтра целиком
-
Фильтр не применяется: разбор причин - когда фильтр не отбирает вовсе
-
Витрина каталога: список товаров, разделы и постраничная навигация - что фильтр отбирает
-
Компоненты 2.0 - устройство компонентов целиком
-
Сортировка товаров в разделе: поле сортировки, наличие, цена - порядок уже отобранных товаров
-
Массовая правка товаров: обновление свойств скриптом - когда индекс приходится пересобирать
-
Highload-блоки на практике: справочники и их данные - работа со справочниками
-
Фильтр по свойствам предложений: настройка, индекс, вывод - индекс для инфоблока предложений
-
Количество товаров в разделе: подсчёт, вложенность, кэш - другие числа и другой механизм
-
Умный фильтр изнутри: от адреса до выборки товаров - устройство индекса, из которого берутся числа