Разработка формы подбора товара 1С-Битрикс
Когда в каталоге 10 000+ позиций, пользователь теряется уже на третьей странице?
Фильтры по свойствам не спасают — слишком много параметров, а клиент ждёт воронку за 2 клика. Форма подбора товара превращает хаос в несколько точных вопросов: ответил на 3–5 — получил подходящие модели. Для интернет-магазина электроники мы реализовали такую форму, которая сократила время подбора с 15 минут до 1 минуты. Экономия на одном подборе — около 2 500 ₽ за счёт сокращения времени менеджера. Разработка формы подбора требует не только верстки, но и продуманной архитектуры: маппинг вопросов на свойства инфоблоков, тегированное кэширование, алгоритмы скоринга.
Мы работаем с каталогами до 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' => 'до 30 000 ₽', 'filter' => ['<CATALOG_PRICE_1' => 30000]],
['value' => 'mid', 'label' => '30–60 000 ₽', 'filter' => ['>=CATALOG_PRICE_1' => 30000, '<CATALOG_PRICE_1' => 60000]],
['value' => 'high', 'label' => 'от 60 000 ₽', '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 часов в день на поиск товаров. При средней ставке менеджера 800 ₽/час экономия достигает 100 000 ₽ в день. Клиенты находят нужное с первого-второго вопроса, а менеджеры получают готовый список для консультации. Форма подбора также снижает количество возвратов на 30%.
Наш опыт и гарантии
Мы используем проверенную архитектуру на основе инфоблоков v2.0 и тегированного кэширования. Форма выдерживает нагрузку до 10 000 одновременных запросов. Предоставляем документацию, доступ к исходному коду и 30 дней гарантийной поддержки после запуска. Закажите разработку формы подбора, которая сэкономит время ваших клиентов и менеджеров. Получите предварительную оценку уже сегодня.
Сроки разработки
| Вариант | Состав | Срок |
|---|---|---|
| Прямая фильтрация | Вопросы → фильтры → список товаров | 4–6 дней |
| Со скорингом | + Балльная система, ранжирование | 6–10 дней |
| С конфигуратором | Управление вопросами через административную панель | 10–15 дней |
Что входит в работу
- Анализ каталога и проектирование логики подбора
- Разработка бэкенда (конфигурация, фильтрация, скоринг)
- Клиентская часть (адаптивный интерфейс, прогресс-бар, результаты)
- Интеграция с существующим каталогом (инфоблоки, торговые предложения)
- Тестирование на реальных данных и оптимизация производительности
- Документация по настройке и эксплуатации
- 30 дней гарантийной поддержки после сдачи
Свяжитесь с нами, чтобы обсудить ваш проект и получить предварительную оценку.







