При открытии карточки товара на сайте одежды покупатель видит таблицу размеров — но в 60% случаев выбирает не свой размер. Мы переписали логику: вместо статической таблицы — динамический алгоритм, который на основе роста, веса и обхватов выдаёт конкретный размер с учётом посадки модели. За 10 лет реализовали более 50 таких советников на 1С-Битрикс. После внедрения доля возвратов по причине «не подошёл» падает на 15–20%, а конверсия в корзину со страницы товара растёт на 12–18%.
По данным одного из проектов, точность рекомендации выросла с 60% до 85%, а инвестиции в разработку окупаются за 2–3 месяца за счёт сокращения логистики и повторных заказов. При среднем чеке возврата $14–20. снижение на 18% даёт экономию 270 тыс. руб. на каждые 1 000 заказов.
Алгоритм подбора работает на основе параметров
Сначала связываем три набора данных:
- Мерки покупателя (рост, вес, обхваты)
- Размерная сетка товара: для каждого размера задаём диапазоны физических мерок с учётом посадки (slim – узкий допуск, oversized – широкий)
- Остатки: проверяем, есть ли рекомендованный размер на складе, иначе предлагаем альтернативу
Ключевой момент — диапазоны мерок, а не точные значения. Размер 46 подходит для груди 88–92 см, а не строго 90. Ширина диапазона зависит от типа посадки: slim fit — ±2 см, oversized — ±5 см. Если все мерки попадают в один диапазон — размер считается идеальным. Если мерки разбросаны между двумя соседними размерами — алгоритм выбирает больший или меньший в зависимости от посадки и предпочтений (например, для облегающей посадки выбирает меньший).
Подбор по параметрам превосходит обычную таблицу размеров
| Критерий | Таблица размеров (статическая) | Подбор по параметрам (алгоритмический) |
|---|---|---|
| Точность | ~60% (покупатель сам выбирает) | ~85% (система рассчитывает) |
| Учёт посадки | Нет | Slim/regular/oversized |
| Альтернатива | Нет | Автоматический подбор соседнего размера |
| Интеграция с остатками | Нет | Проверка после рекомендации |
| Персонализация | Нет | Сохранение мерок в ЛК |
Архитектура данных
Расширяем структуру из таблицы размеров дополнительными параметрами допусков. Используем HL-блок для хранения правил:
CREATE TABLE b_size_fit_rules ( ID SERIAL PRIMARY KEY, CHART_ID INT NOT NULL REFERENCES b_size_charts(ID), SIZE_RU VARCHAR(10), CHEST_MIN NUMERIC(5,1), CHEST_MAX NUMERIC(5,1), WAIST_MIN NUMERIC(5,1), WAIST_MAX NUMERIC(5,1), HIPS_MIN NUMERIC(5,1), HIPS_MAX NUMERIC(5,1), HEIGHT_MIN SMALLINT, HEIGHT_MAX SMALLINT, WEIGHT_MIN SMALLINT, WEIGHT_MAX SMALLINT, FIT_TYPE VARCHAR(20) -- 'slim', 'regular', 'oversized' ); Алгоритм подбора
// SizeFitAdvisor.php class SizeFitAdvisor { public function recommend(array $measurements, int $chartId, string $fitType = 'regular'): array { $rules = SizeFitRulesTable::getList([ 'filter' => ['=CHART_ID' => $chartId, '=FIT_TYPE' => $fitType], 'order' => ['SIZE_RU' => 'ASC'], ])->fetchAll(); $scores = []; foreach ($rules as $rule) { $score = 0; $matched = 0; foreach (['CHEST', 'WAIST', 'HIPS'] as $param) { if (!isset($measurements[$param])) continue; $val = (float) $measurements[$param]; $min = (float) $rule[$param . '_MIN']; $max = (float) $rule[$param . '_MAX']; if ($val >= $min && $val <= $max) { $score++; } elseif ($val < $min) { $score -= ($min - $val) / 10; } else { $score -= ($val - $max) / 10; } $matched++; } if ($matched > 0) { $scores[$rule['SIZE_RU']] = $score / $matched; } } arsort($scores); $best = array_key_first($scores); $next = array_keys($scores)[1] ?? null; return ['primary' => $best, 'alternative' => $next, 'scores' => $scores]; } } Алгоритм возвращает не один размер, а основную рекомендацию и альтернативу. Это важно: если основной размер недоступен, показываем альтернативу с пометкой «если 46 нет, возьмите 48 — подойдёт при вашем телосложении».
Проверка доступности рекомендованного размера
После получения рекомендации сервер проверяет остатки предложений с этим размером. Если товара нет, сразу предлагается альтернативный размер. Логика реализуется через стандартный CIBlockElement::GetList с фильтром по свойству размера и остаткам.
Форма подбора на карточке товара
Типичные ошибки при реализации формы:
- Спрашивать все мерки сразу — отпугивает. Лучше пошаговый опрос с прогресс-баром.
- Не проверять остатки до выдачи результата — пользователь расстраивается.
- Игнорировать тип посадки — для облегающей и свободной одежды нужны разные сетки.
Одношаговая форма (все мерки сразу) — для опытных покупателей:
<form class="size-advisor-form"> <div class="form-row"> <label>Рост (см): <input type="number" name="height" min="140" max="220"></label> <label>Вес (кг): <input type="number" name="weight" min="40" max="200"></label> </div> <div class="form-row"> <label>Обхват груди (см): <input type="number" name="chest" min="60" max="160"></label> <label>Обхват талии (см): <input type="number" name="waist" min="50" max="150"></label> <label>Обхват бёдер (см): <input type="number" name="hips" min="70" max="170"></label> </div> <label>Посадка: <select name="fit_type"> <option value="slim">Облегающая</option> <option value="regular" selected>Стандартная</option> <option value="oversized">Свободная</option> </select> </label> <button type="submit">Подобрать размер</button> </form> AJAX-запрос к PHP-контроллеру
Форма отправляет данные на сервер, потому что:
- Алгоритм подбора на сервере — данные не доступны конкурентам
- Сервер сразу проверяет остатки и возвращает финальный ответ
- Результат можно персонализировать (сохранить мерки для авторизованного пользователя)
// SizeAdvisorController.php public function recommendAction(): array { $measurements = [ 'CHEST' => (float) $this->request->getPost('chest'), 'WAIST' => (float) $this->request->getPost('waist'), 'HIPS' => (float) $this->request->getPost('hips'), ]; $fitType = $this->request->getPost('fit_type', 'regular'); $productId = (int) $this->request->getPost('product_id'); $chartId = $this->getChartForProduct($productId); $advisor = new SizeFitAdvisor(); $result = $advisor->recommend($measurements, $chartId, $fitType); $availability = $advisor->checkAvailability($result['primary'], $productId); if (is_object(global_user()) && !global_user()->IsGuest()) { UserMeasurementsTable::saveForUser(global_user()->GetID(), $measurements); } return [ 'recommended_size' => $result['primary'], 'alternative_size' => $result['alternative'], 'available' => $availability['available'], 'offers' => $availability['offers'], ]; } Сохранение мерок в личном кабинете
Если пользователь авторизован, мерки сохраняются в отдельной таблице и подставляются при следующем обращении к советнику — даже на другом товаре. В личном кабинете доступен раздел «Мои мерки» для ручного редактирования.
Что входит в работу
- Документация по настройке размерных сеток и правил расчёта
- Исходный код модуля с комментариями
- Доступ к Git-репозиторию с историей изменений
- Инструкцию по загрузке размеров через админку Битрикс
- Обучение контент-менеджеров (1 час онлайн)
- Техническая поддержка на 14 дней после запуска
Сроки
| Вариант | Что входит | Срок |
|---|---|---|
| Базовый советник | Форма, алгоритм, результат | 1–2 недели |
| С проверкой остатков | + интеграция с ТП, остатки | 2–3 недели |
| + ЛК с мерками | + сохранение профиля | +1 неделя |
Советник по размеру на основе мерок даёт наиболее точную рекомендацию и максимально снижает вероятность возврата. Из всех размерных инструментов — самый трудоёмкий, но и самый эффективный. Свяжитесь с нами для расчёта стоимости и сроков под ваш проект. Получите подробный план интеграции советника в ваш каталог. Закажите разработку, и мы покажем, сколько вы сэкономите на возвратах.







