Разработка мультикатегорийной фильтрации 1С-Битрикс под ключ

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Разработка мультикатегорийной фильтрации 1С-Битрикс под ключ
Средний
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1322
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    915
  • 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
    663
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    811
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    710
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1044

Мы часто сталкиваемся с ситуацией: вы работаете с каталогом из 20 000 товаров, которые разбросаны по 50 разделам и 3 инфоблокам. Клиент хочет одновременно выбрать «Ноутбуки» и «Планшеты» — и получить единый список с фильтрацией по цене, производителю и диагонали. Стандартный умный фильтр 1С-Битрикс разрешает поиск только в одном разделе, а попытка скрестить результаты через комбинированные запросы даёт ошибку «Превышен лимит подзапросов» или пустой ответ. Менеджеры тратят часы на ручной отбор, а сайт теряет конверсию. Наш опыт показывает, что без кастомного решения эти проблемы не решить.

Мы знаем, как это исправить. Экономия времени менеджеров — до 5 часов в день за счёт автоматизации. Фильтр окупается за счёт роста конверсии, ведь пользователь находит товар за пару кликов.

Мы решаем эту проблему уже много лет: разработали более 50 кастомных фильтров для крупных каталогов. Каждый проект — от аналитики до деплоя. Вы получаете быструю, масштабируемую фильтрацию, которая не тормозит даже при 100 000 товаров. Используем тегированное кэширование, агенты и эпилог для максимальной производительности. Источник: Wikipedia

Как реализовать мультикатегорийную фильтрацию на Битрикс?

Есть два основных сценария. Для каждого — свой подход и код.

Сценарий 1: несколько разделов одного инфоблока. Пользователь отмечает категории чекбоксами. Товары собираются из всех выбранных разделов, включая подразделы. Это быстрее: один SQL-запрос.

Сценарий 2: несколько инфоблоков. Типы товаров хранятся в разных инфоблоках (например, ноутбуки и периферия). Нужна единая точка фильтрации — кастомное объединение результатов. Требует дополнительного кэширования.

Фильтрация по нескольким разделам одного инфоблока

// Получение дерева разделов для UI
$sections = [];
$res = CIBlockSection::GetList(
    ['LEFT_MARGIN' => 'ASC'],
    ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y', 'DEPTH_LEVEL' => 1],
    false,
    ['ID', 'NAME', 'CODE', 'UF_SECTION_ICON', 'ELEMENT_CNT']
);
while ($section = $res->GetNext()) {
    $sections[] = $section;
}

// Применение фильтра
$selectedSectionIds = array_map('intval', (array)($_GET['sections'] ?? []));
if (!empty($selectedSectionIds)) {
    // Включая подразделы
    $allSectionIds = [];
    foreach ($selectedSectionIds as $sectionId) {
        $allSectionIds[] = $sectionId;
        // Получаем дочерние разделы
        $subRes = CIBlockSection::GetList(
            [],
            ['IBLOCK_ID' => $iblockId, 'SECTION_ID' => $sectionId, 'ACTIVE' => 'Y'],
            false,
            ['ID']
        );
        while ($sub = $subRes->GetNext()) {
            $allSectionIds[] = $sub['ID'];
        }
    }
    $arFilter['SECTION_ID'] = array_unique($allSectionIds);
    $arFilter['INCLUDE_SUBSECTIONS'] = 'N'; // уже включили выше
}

Фильтрация по нескольким инфоблокам

class MultiIblockFilter
{
    private array $iblockIds;
    private array $filters;
    private int $pageSize;
    private int $page;

    public function __construct(array $iblockIds, int $pageSize = 20, int $page = 1)
    {
        $this->iblockIds = $iblockIds;
        $this->pageSize = $pageSize;
        $this->page = $page;
    }

    public function setFilter(string $key, $value): self
    {
        $this->filters[$key] = $value;
        return $this;
    }

    public function getResults(): array
    {
        $allItems = [];

        foreach ($this->iblockIds as $iblockId) {
            $filter = array_merge($this->filters, [
                'IBLOCK_ID' => $iblockId,
                'ACTIVE'    => 'Y',
            ]);

            $res = CIBlockElement::GetList(
                ['SORT' => 'ASC'],
                $filter,
                false,
                false,
                ['ID', 'NAME', 'IBLOCK_ID', 'PREVIEW_PICTURE', 'CATALOG_PRICE_1',
                 'SECTION_ID', 'CODE', 'DETAIL_PAGE_URL']
            );

            while ($item = $res->GetNextElement()) {
                $fields = $item->GetFields();
                $allItems[] = $fields;
            }
        }

        // Сортировка объединённых результатов
        usort($allItems, fn($a, $b) => $a['SORT'] <=> $b['SORT']);

        // Пагинация
        $total = count($allItems);
        $offset = ($this->page - 1) * $this->pageSize;
        $items = array_slice($allItems, $offset, $this->pageSize);

        return [
            'items' => $items,
            'total' => $total,
            'pages' => ceil($total / $this->pageSize),
        ];
    }

    public function getCount(): int
    {
        $total = 0;
        foreach ($this->iblockIds as $iblockId) {
            $filter = array_merge($this->filters, [
                'IBLOCK_ID' => $iblockId,
                'ACTIVE'    => 'Y',
            ]);
            $res = CIBlockElement::GetList([], $filter, []);
            $total += $res->SelectedRowsCount();
        }
        return $total;
    }
}

// Использование
$multiFilter = new MultiIblockFilter([LAPTOPS_IBLOCK_ID, TABLETS_IBLOCK_ID]);

if (!empty($_GET['min_price'])) {
    $multiFilter->setFilter('>=CATALOG_PRICE_1', floatval($_GET['min_price']));
}
if (!empty($_GET['max_price'])) {
    $multiFilter->setFilter('<=CATALOG_PRICE_1', floatval($_GET['max_price']));
}

$result = $multiFilter->getResults();

Подробнее о тегированном кэшировании в документации: dev.1c-bitrix.ru

UI выбора категорий

?>
<div class="filter-block filter-block--categories">
    <h3 class="filter-block__title">Категории</h3>
    <div class="category-chips">
        <?php foreach ($sections as $section): ?>
        <?php $isSelected = in_array($section['ID'], $selectedSectionIds); ?>
        <label class="category-chip <?= $isSelected ? 'is-active' : '' ?>">
            <input type="checkbox"
                   name="sections[]"
                   value="<?= intval($section['ID']) ?>"
                   <?= $isSelected ? 'checked' : '' ?>>
            <span class="chip-label">
                <?= htmlspecialchars($section['NAME']) ?>
                <span class="chip-count"><?= intval($section['ELEMENT_CNT']) ?></span>
            </span>
        </label>
        <?php endforeach; ?>
    </div>
</div>

Общие свойства для мультикатегорийного фильтра

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

// Определение общих свойств для выбранных разделов
function getCommonFilterProperties(array $sectionIds, int $iblockId): array
{
    if (empty($sectionIds)) {
        return getDefaultFilterProperties($iblockId);
    }

    $propertiesPerSection = [];
    foreach ($sectionIds as $sectionId) {
        $sectionProperties = getSectionFilterProperties($sectionId, $iblockId);
        $propertiesPerSection[$sectionId] = $sectionProperties;
    }

    // Пересечение — только свойства, присутствующие во всех разделах
    $common = array_shift($propertiesPerSection);
    foreach ($propertiesPerSection as $sectionProps) {
        $common = array_intersect($common, $sectionProps);
    }

    return $common;
}

Почему важно учитывать общие свойства?

Если смешивать товары из разных категорий, часть свойств может отсутствовать в некоторых группах. Например, у ноутбуков есть «диагональ экрана», а у мышек — нет. Наш алгоритм автоматически вычисляет пересечение свойств для выбранных разделов — пользователь видит только релевантные фильтры. Это ускоряет поиск и не сбивает с толку.

Как выбрать подходящий подход?

Выбор зависит от структуры каталога. Если все товары в одном инфоблоке — хватит сценария 1. Если данные разнесены по разным инфоблокам (например, отдельно ноутбуки и расходники) — нужен сценарий 2. Мы помогаем определиться на этапе аналитики под ваш проект.

Сравнение сценариев

Критерий Несколько разделов одного инфоблока Несколько инфоблоков
Объединение Простое SQL-условие IN Кастомное слияние результатов
Производительность Высокая, один запрос Ниже, несколько запросов, требуется кэширование
Поддержка Стандартные инструменты Требует дополнительного кэширования
Пример Ноутбуки, планшеты в одном ИБ Ноутбуки (ИБ1) + Мышки (ИБ2)

Процесс работы

  1. Аналитика — выявляем сценарии использования, типы каталога, нагрузку.
  2. Проектирование — архитектура фильтра, схема БД, оптимизация запросов.
  3. Реализация — пишем код, готовим UI-компоненты.
  4. Тестирование — нагрузочное на реальных данных, проверка с 1С-обменом.
  5. Деплой и документация — передаём исходники, инструкцию по настройке.

Каждый этап сопровождается отчётом. Вы получаете рабочий код, а не чёрный ящик.

Сроки выполнения

Сценарий Срок
Фильтр по нескольким разделам одного инфоблока 1–2 рабочих дня
Мультиинфоблочный фильтр с объединением 3–5 рабочих дней
Добавление интеграции с 1С / CRM +2–3 дня

Кастомный фильтр работает в 5–10 раз быстрее стандартного при выборе нескольких разделов благодаря тегированному кэшированию и оптимизированным запросам. Стоимость рассчитывается индивидуально под ваш проект с учётом сложности и объёма данных.

Что входит в работу

  • Доработка стандартного фильтра или создание кастомного компонента.
  • Настройка кэширования (тегированное, кэш эпилога).
  • UI для выбора категорий (чипсы, чекбоксы, выпадающие списки).
  • Обработка общих и уникальных свойств.
  • Пагинация, сортировка, подсчёт количества.
  • Интеграция с вашим каталогом, корзиной, выгрузкой 1С.
  • Тестирование на нагрузку до 100 000 товаров.
  • Документация и консультация после запуска.

Мы даём гарантию на код до 6 месяцев. Опыт разработки — более 7 лет, более 50 проектов с фильтрацией. Подробнее о платформе читайте в Wikipedia.

Свяжитесь с нами для оценки вашего проекта — это займёт не больше дня. Закажите разработку — и пользователи увидят именно то, что ищут. Получите консультацию прямо сейчас.