Разработка формы подбора товара 1С-Битрикс
Когда в каталоге 10 000+ позиций, пользователь теряется уже на третьей странице?
Фильтры по свойствам не спасают — слишком много параметров, а клиент ждёт воронку за 2 клика. Форма подбора товара превращает хаос в несколько точных вопросов: ответил на 3–5 — получил подходящие модели. Для интернет-магазина электроники мы реализовали такую форму, которая сократила время подбора с 15 минут до 1 минуты. Экономия на одном подборе — около $22–32 за счёт сокращения времени менеджера. Разработка формы подбора требует не только верстки, но и продуманной архитектуры: маппинг вопросов на свойства инфоблоков, тегированное кэширование, алгоритмы скоринга.
Мы работаем с каталогами до 1 миллиона товаров. Используем тегированное кэширование, чтобы форма не тормозила при пиковых нагрузках. На рынке с 2015 года, реализовали 45+ проектов по разработке подборщиков. Оценим ваш проект бесплатно — свяжитесь с нами, чтобы обсудить детали.
Как устроена разработка формы подбора товара в 1С-Битрикс
Форма подбора — интерактивный помощник, который задаёт пользователю вопросы и на выходе предлагает конкретные товары из каталога. Применяется там, где ассортимент велик или товары технически сложны: выбор ноутбука, шин, краски, промышленного оборудования. По сути это рекомендательная система, замаскированная под опросник. Ключевая техническая задача — алгоритм сопоставления ответов с товарами в инфоблоке.
Два подхода к подбору
1. Прямая фильтрация. Каждый ответ пользователя = фильтр по свойству инфоблока. Итог = пересечение всех фильтров. Просто, предсказуемо, но плохо работает когда пользователь дал «неточные» ответы — результат может быть пустым.
2. Scoring (балльная система). Каждый вариант ответа добавляет баллы определённым товарам или категориям. Товары ранжируются по сумме баллов. Лучше для рекомендаций, сложнее в настройке.
Для большинства каталогов — комбинация: обязательные фильтры (например, бюджет) + скоринг по дополнительным критериям.
| Характеристика | Прямая фильтрация | Скоринговая система |
|---|---|---|
| Точность | Высокая при совпадении | Высокая при неполных данных |
| Гибкость | Низкая | Высокая |
| Сложность настройки | Низкая | Средняя |
| Поведение при пустом результате | Показывает пустоту | Показывает ближайшие варианты |
Почему скоринговая система эффективнее фильтрации?
Прямая фильтрация часто даёт пустой результат — достаточно одного неверного ответа. Scoring накапливает баллы по тегам товаров и сортирует их по релевантности. Даже если пользователь ошибся, он видит ближайшие варианты. В 95% случаев форма выдаёт хотя бы один релевантный товар. Для консультаций с клиентами это критично: менеджер получает список для разговора, а не "ничего не найдено".
Реализация: структура и алгоритм
Конфигурация подборщика хранится в b_option или HL-блоке. Режимы фильтрации: range (числовые поля), property (свойства-справочники), scoring (накопление баллов). Все три режима можно комбинировать в одном вопросе.
Пример конфигурации
$selectorConfig = [ 'iblock_id' => CATALOG_IBLOCK_ID, 'questions' => [ [ 'id' => 'q_budget', 'text' => 'Ваш бюджет', 'type' => 'select', 'filter_mode' => 'range', 'options' => [ ['value' => 'low', 'label' => 'до $270–390', 'filter' => ['<CATALOG_PRICE_1' => 30000]], ['value' => 'mid', 'label' => '$1–600', 'filter' => ['>=CATALOG_PRICE_1' => 30000, '<CATALOG_PRICE_1' => 60000]], ['value' => 'high', 'label' => 'от $540–780', 'filter' => ['>=CATALOG_PRICE_1' => 60000]], ], ], [ 'id' => 'q_purpose', 'text' => 'Для каких задач', 'type' => 'radio', 'filter_mode' => 'property', 'property_code' => 'PURPOSE', 'options' => [ ['value' => 'work', 'label' => 'Работа / офис', 'property_value' => 'WORK'], ['value' => 'gaming', 'label' => 'Игры', 'property_value' => 'GAMING'], ['value' => 'study', 'label' => 'Учёба', 'property_value' => 'STUDY'], ], ], [ 'id' => 'q_weight', 'text' => 'Важен ли вес устройства?', 'type' => 'radio', 'filter_mode' => 'scoring', 'options' => [ ['value' => 'yes', 'label' => 'Да, беру с собой', 'scores' => ['lightweight' => 10]], ['value' => 'no', 'label' => 'Нет, стационарный', 'scores' => ['performance' => 5]], ], ], ], ]; 1С-Битрикс: Инфоблоки v2.0
Алгоритм фильтрации и скоринга
class ProductSelector { private array $config; public function findProducts(array $answers): array { $hardFilters = ['IBLOCK_ID' => $this->config['iblock_id'], 'ACTIVE' => 'Y']; $scoringTags = []; foreach ($this->config['questions'] as $question) { $answer = $answers[$question['id']] ?? null; if ($answer === null) continue; $selectedOption = null; foreach ($question['options'] as $opt) { if ($opt['value'] === $answer) { $selectedOption = $opt; break; } } if (!$selectedOption) continue; switch ($question['filter_mode']) { case 'range': case 'property': $hardFilters = array_merge($hardFilters, $selectedOption['filter'] ?? []); if (isset($question['property_code'], $selectedOption['property_value'])) { $hardFilters['PROPERTY_' . $question['property_code']] = $selectedOption['property_value']; } break; case 'scoring': foreach ($selectedOption['scores'] ?? [] as $tag => $score) { $scoringTags[$tag] = ($scoringTags[$tag] ?? 0) + $score; } break; } } $result = \CIBlockElement::GetList( ['SORT' => 'ASC'], $hardFilters, false, ['nPageSize' => 20], ['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE', 'CATALOG_PRICE_1', 'PROPERTY_TAGS'] ); $products = []; while ($item = $result->GetNext()) { $score = 0; $productTags = explode(',', $item['PROPERTY_TAGS_VALUE'] ?? ''); foreach ($scoringTags as $tag => $tagScore) { if (in_array(trim($tag), array_map('trim', $productTags))) { $score += $tagScore; } } $item['_SCORE'] = $score; $products[] = $item; } usort($products, fn($a, $b) => $b['_SCORE'] <=> $a['_SCORE']); return $products; } } Клиентская часть и обработка результатов
class ProductSelectorUI { constructor(configJson) { this.config = configJson; this.answers = {}; this.step = 0; this.renderStep(); } renderStep() { const question = this.config.questions[this.step]; const container = document.getElementById('selector-step'); container.innerHTML = ` <h3>${question.text}</h3> <div class="selector-options"> ${question.options.map(opt => ` <button class="selector-option" data-value="${opt.value}" data-question="${question.id}"> ${opt.label} </button> `).join('')} </div> `; container.querySelectorAll('.selector-option').forEach(btn => { btn.addEventListener('click', e => { const questionId = e.target.dataset.question; const value = e.target.dataset.value; this.selectAnswer(questionId, value); }); }); this.updateProgress(); } selectAnswer(questionId, value) { this.answers[questionId] = value; if (this.step < this.config.questions.length - 1) { this.step++; this.renderStep(); } else { this.fetchResults(); } } async fetchResults() { document.getElementById('selector-step').innerHTML = '<div class="loading">Подбираем для вас...</div>'; const response = await fetch('/local/ajax/product_selector.php', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({answers: this.answers, sessid: BX.bitrix_sessid()}), }); const data = await response.json(); this.renderResults(data.products); } renderResults(products) { const container = document.getElementById('selector-results'); if (products.length === 0) { container.innerHTML = '<p>К сожалению, по вашим критериям ничего не найдено. <a href="/catalog/">Смотреть весь каталог</a></p>'; return; } container.innerHTML = products.slice(0, 6).map(p => ` <div class="product-card"> <img src="${p.PREVIEW_PICTURE?.SRC || ''}" alt="${p.NAME}"> <h4><a href="${p.DETAIL_PAGE_URL}">${p.NAME}</a></h4> <div class="price">${p.CATALOG_PRICE_1} $</div> <a href="${p.DETAIL_PAGE_URL}" class="btn">Подробнее</a> </div> `).join(''); document.getElementById('selector-container').style.display = 'none'; document.getElementById('selector-results-container').style.display = 'block'; } updateProgress() { const bar = document.getElementById('selector-progress'); if (bar) bar.style.width = ((this.step / this.config.questions.length) * 100) + '%'; } } Если подходящих товаров нет — форма предлагает оставить контакт для консультации:
if (empty($products)) { echo json_encode([ 'products' => [], 'show_contact_form' => true, 'message' => 'Мы подберём для вас индивидуально', ]); exit; } Если пользователь оставляет контакт после подбора — сохраняем выбранные параметры в комментарии лида. Это даёт менеджеру полную информацию о запросе клиента.
Как форма подбора ускоряет поиск товаров?
Средняя экономия времени на один запрос — 15 минут. В масштабах интернет-магазина с 500 посещениями в день это даёт экономию 125 часов в день на поиск товаров. При средней ставке менеджера $7–10/час экономия достигает $900–1.3k в день. Клиенты находят нужное с первого-второго вопроса, а менеджеры получают готовый список для консультации. Форма подбора также снижает количество возвратов на 30%.
Наш опыт и гарантии
Мы используем проверенную архитектуру на основе инфоблоков v2.0 и тегированного кэширования. Форма выдерживает нагрузку до 10 000 одновременных запросов. Предоставляем документацию, доступ к исходному коду и 30 дней гарантийной поддержки после запуска. Закажите разработку формы подбора, которая сэкономит время ваших клиентов и менеджеров. Получите предварительную оценку уже сегодня.
Сроки разработки
| Вариант | Состав | Срок |
|---|---|---|
| Прямая фильтрация | Вопросы → фильтры → список товаров | 4–6 дней |
| Со скорингом | + Балльная система, ранжирование | 6–10 дней |
| С конфигуратором | Управление вопросами через административную панель | 10–15 дней |
Что входит в работу
- Анализ каталога и проектирование логики подбора
- Разработка бэкенда (конфигурация, фильтрация, скоринг)
- Клиентская часть (адаптивный интерфейс, прогресс-бар, результаты)
- Интеграция с существующим каталогом (инфоблоки, торговые предложения)
- Тестирование на реальных данных и оптимизация производительности
- Документация по настройке и эксплуатации
- 30 дней гарантийной поддержки после сдачи
Свяжитесь с нами, чтобы обсудить ваш проект и получить предварительную оценку.







