Разработка модуля фильтрации каталога 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка модуля фильтрации каталога 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка модуля фильтрации каталога 1С-Битрикс

Стандартный компонент catalog.section.list с компонентом фильтра catalog.section.list.filter работает из коробки, но имеет известные ограничения. При большом количестве свойств (b_iblock_element_prop_s*, b_iblock_element_prop_m*) запросы становятся медленными из-за множественных JOIN. Чекбоксы показывают все возможные значения без учёта того, сколько товаров за ними стоит — пользователь кликает на фильтр и получает пустой результат. Динамическая перестройка фильтра при каждом изменении убивает производительность на каталогах от 10 000 позиций.

Проблема N+1 и денормализация

Корень проблемы производительности стандартного фильтра — архитектура хранения свойств инфоблока. Значения хранятся в нескольких таблицах в зависимости от типа (b_iblock_element_prop_s* для строк, b_iblock_element_prop_m* для множественных), и для каждого свойства нужен отдельный 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 для конкретного товара и через агент для массового пересчёта.

Детально: умные чекбоксы с счётчиками

Это ключевая фича — показывать рядом с каждым значением фильтра количество товаров, которые за ним стоят с учётом уже выбранных фильтров. Такое поведение называется faceted search.

-- Подсчёт вариантов для фильтра "Бренд"
-- с учётом уже выбранного фильтра "Цвет: черный"
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-индекс по JSONB делает поиск эффективным.

Кеширование фасетов. Результаты подсчётов кешируются с тегами по разделу и набору активных фильтров. При изменении любого товара в разделе тег сбрасывается. TTL кеша — 30 минут.

URL-схема фильтра

Фильтр строит «красивые» URL, дружелюбные к SEO:

  • /catalog/smartphones/brand-samsung/color-black/ — постраничный список с фильтрами
  • /catalog/smartphones/brand-samsung/ — категориальный фильтр с собственным H1 и описанием

Ключевые страницы фильтра (бренд, популярная комбинация свойств) могут иметь уникальные мета-теги, задаваемые через административный интерфейс модуля. Остальные формируются автоматически по шаблону.

AJAX-обновление без перезагрузки

При изменении фильтра страница не перезагружается: AJAX-запрос уходит на /api/catalog/filter/, сервер возвращает JSON с ID отфильтрованных товаров и обновлёнными счётчиками фасетов, фронтенд обновляет список товаров и чекбоксы. История браузера обновляется через history.pushState.

Ранжирование результатов

Помимо фильтрации, модуль управляет сортировкой: по цене, популярности (количество заказов из b_sale_basket), новизне, рейтингу. «Популярность» пересчитывается агентом раз в сутки и хранится в myvendor_filter_index.popularity_score.

Сроки разработки

Масштаб Состав Срок
Базовый Денормализованный индекс + чекбоксы + диапазон цен 3–4 недели
Средний + умные счётчики (фасеты) + AJAX + URL-схема 5–7 недель
Расширенный + SEO-страницы фильтра + персонализация сортировки 8–11 недель

Количество свойств инфоблока и объём каталога — главные факторы выбора архитектуры. При 200+ свойствах JSONB-подход требует тщательного проектирования схемы индекса.