Разработка модуля фильтрации каталога 1С-Битрикс
Представьте: ваш каталог разросся до 50 000 товаров, а стандартный фильтр Битрикс начал грузить страницу по 10 секунд. Мы сталкивались с таким на каждом втором проекте. За 8 лет разработки модулей для Битрикс мы выработали решение, которое даёт гарантию производительности даже на каталогах с 200+ свойствами. Экономия на серверных ресурсах за счёт оптимизированных запросов становится значительным преимуществом.
Стандартный компонент catalog.section.list с фильтром catalog.section.list.filter работает из коробки, но при большом количестве свойств (b_iblock_element_prop_s*, b_iblock_element_prop_m*) запросы становятся медленными из-за множественных JOIN. Чекбоксы показывают все возможные значения без учёта того, сколько товаров за ними стоит — пользователь кликает и получает пустой результат. Динамическая перестройка фильтра убивает производительность на каталогах от 10 000 позиций.
Как денормализация индекса ускоряет фильтрацию?
Корень проблемы — архитектура хранения свойств инфоблока. Для каждого свойства нужен отдельный JOIN. Наше решение — денормализованный индекс фильтра. Модуль создаёт и поддерживает таблицу myvendor_filter_index, где для каждого товара хранится плоская структура значений всех фильтруемых свойств в JSONB:
CREATE TABLE myvendor_filter_index (
element_id INT PRIMARY KEY,
section_id INT NOT NULL,
price_min DECIMAL(12,2),
in_stock BOOLEAN,
props JSONB NOT NULL -- {"brand": "Samsung", "color": ["black", "white"]}
);
CREATE INDEX idx_filter_props ON myvendor_filter_index USING gin(props);
CREATE INDEX idx_filter_section ON myvendor_filter_index(section_id);
CREATE INDEX idx_filter_price ON myvendor_filter_index(price_min);
Индекс обновляется через событие OnAfterIBlockElementUpdate конкретного товара и через агент для массового пересчёта. По нашим тестам, JSONB-индекс в 15 раз быстрее стандартных JOIN на каталогах от 50 000 товаров.
Детали обновления индекса
Агент запускается раз в 5 минут при наличии изменений. Он собирает ID изменённых элементов и обновляет только их записи в myvendor_filter_index. При массовом импорте из 1С индекс перестраивается по расписанию — ночной агент выполняет полную переиндексацию.
Почему умные счётчики (facets) важны для UX?
Это ключевая фича — показывать рядом с каждым значением фильтра количество товаров, которые за ним стоят с учётом уже выбранных фильтров. Такое поведение называется фасетный поиск.
-- Подсчёт вариантов для фильтра "Бренд"
-- с учётом уже выбранного фильтра "Цвет: черный"
SELECT
props->>'brand' AS brand,
COUNT(*) AS cnt
FROM myvendor_filter_index
WHERE
section_id = :section_id
AND in_stock = true
AND props @> '{"color": "black"}'::jsonb
GROUP BY props->>'brand'
ORDER BY cnt DESC;
Этот запрос возвращает все бренды с количеством чёрных товаров в наличии. Для каждого свойства выполняется отдельный такой запрос — но это быстро благодаря GIN-индексу. Результаты подсчётов кешируются с тегами по разделу и набору активных фильтров. При изменении любого товара тег сбрасывается. TTL кеша — 30 минут.
Как работает AJAX-обновление?
При изменении фильтра страница не перезагружается: AJAX-запрос уходит на /api/catalog/filter/, сервер возвращает JSON с ID отфильтрованных товаров и обновлёнными счётчиками. Фронтенд обновляет список и чекбоксы. История браузера обновляется через history.pushState. Это обеспечивает плавную навигацию без мерцания.
Как выглядит URL-схема фильтра?
Фильтр строит «красивые» URL, дружелюбные к SEO:
-
/catalog/smartphones/brand-samsung/color-black/— постраничный список с фильтрами -
/catalog/smartphones/brand-samsung/— категориальный фильтр с собственным H1 и описанием
Ключевые страницы фильтра могут иметь уникальные мета-теги, задаваемые через административный интерфейс модуля. Остальные формируются автоматически по шаблону. Это улучшает индексацию и ранжирование в поисковиках.
Ранжирование результатов
Помимо фильтрации, модуль управляет сортировкой: по цене, популярности (количество заказов из b_sale_basket), новизне, рейтингу. «Популярность» пересчитывается агентом раз в сутки и хранится в myvendor_filter_index.popularity_score.
Сравнение: стандартный фильтр vs наш модуль
| Параметр | Стандартный фильтр Битрикс | Наш модуль |
|---|---|---|
| Время запроса (50k товаров, 100 свойств) | 8–12 сек | 0.3–0.8 сек |
| Количество JOIN в запросе | 10–100+ | 1 (к денормализованной таблице) |
| Умные счётчики | Нет | Да |
| SEO-URL | /catalog/?filter=... |
/catalog/brand-samsung/ |
| Кэширование результатов | Ограниченное | Тегированное с TTL 30 мин |
Этапы разработки модуля фильтрации
- Аудит текущей архитектуры каталога и свойств инфоблока.
- Проектирование схемы денормализованного индекса под ваш объём данных.
- Реализация фасадов с умными счётчиками и кешированием.
- Настройка AJAX-обновления и красивых URL.
- Оптимизация запросов для каталогов до 500 000 товаров.
- Документация по поддержке и дообучение администраторов.
Сроки разработки
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | Денормализованный индекс + чекбоксы + диапазон цен | 3–4 недели |
| Средний | + умные счётчики (фасеты) + AJAX + URL-схема | 5–7 недель |
| Расширенный | + SEO-страницы фильтра + персонализация сортировки | 8–11 недель |
Количество свойств инфоблока и объём каталога — главные факторы выбора архитектуры. При 200+ свойствах JSONB-подход требует тщательного проектирования схемы индекса.
Почему выбирают нас
Мы разрабатываем модули для Битрикс более 8 лет, реализовали 40+ проектов с фильтрацией каталогов. Даём гарантию производительности на объёмах от 10 000 товаров. Закажите разработку модуля фильтрации — свяжитесь с нами для предварительной оценки вашего проекта. Получите консультацию сегодня.







