Пустота на карточке товара или блок «похожие» по свойствам — конверсия падает. Покупатель не видит ценности: товары со схожими характеристиками не отражают реальное поведение. Блок совместных покупок решает задачу иначе — он опирается на статистику заказов. Такой подход даёт в 2–3 раза больше кликов и на 15–30% увеличивает средний чек. Мы реализовали его на 1С-Битрикс для десятков проектов — от каталогов в 500 товаров до маркетплейсов с миллионом позиций. Решение подходит для любой редакции: «Малый бизнес», «Бизнес» или «Энтерпрайз». Хотите оценить эффект на своём каталоге? Свяжитесь с нами — покажем демо.
Как работает блок «с этим товаром покупают»?
Логика: для каждого товара A находим все заказы, где он куплен, и смотрим, какие другие товары встречаются в тех же заказах. Чем чаще пара встречается — тем выше recommendation score. Мы используем порог в 3 совместные покупки за последние 90 дней, чтобы отсечь случайные совпадения.
Источники данных и SQL
Основная информация лежит в таблицах b_sale_order (заказы) и b_sale_basket (позиции). Запрос собирает товары, купленные вместе, за последние 90 дней — этого достаточно, чтобы ассортиментные изменения быстро отражались.
SELECT
b2.product_id AS recommended_id,
COUNT(DISTINCT b2.order_id) AS co_purchase_count
FROM b_sale_basket b1
JOIN b_sale_order o ON b1.order_id = o.id
AND o.canceled = 'N'
AND o.status_id NOT IN ('F')
JOIN b_sale_basket b2 ON b1.order_id = b2.order_id
AND b2.product_id != b1.product_id
AND b2.product_id IS NOT NULL
WHERE
b1.product_id = :productId
AND o.date_insert >= DATE_SUB(NOW(), INTERVAL 90 DAY)
GROUP BY b2.product_id
HAVING co_purchase_count >= 3
ORDER BY co_purchase_count DESC
LIMIT 20;
Результаты сохраняются в отдельную таблицу custom_co_purchases с первичным ключом (product_id, recommended_id). Это позволяет делать быстрый lookup без тяжёлых запросов каждый раз. Подробнее о структуре таблиц модуля sale можно узнать в документации Битрикс.
Предрасчёт через агент
Запускать такой SQL при каждом просмотре карточки — убийственно для производительности. Поэтому мы делаем предрасчёт для топ-500 товаров с помощью агента, который запускается ночью.
// Агент в local/php_interface/init.php
function RecalcCoPurchasesAgent(): string {
$topProducts = getTopSellingProducts(500);
foreach ($topProducts as $productId) {
$recs = calcCoPurchases($productId);
saveToCoPurchases($productId, $recs);
}
return 'RecalcCoPurchasesAgent();';
}
Агент пересчитывает данные для селлера раз в сутки. Для не топовых товаров используем fallback.
Компонент с тегированным кешированием
Вывод блока реализован через компонент company:catalog.co_purchases. Компонент использует тегированный кеш, чтобы страницы карточек не пересчитывались при каждом открытии. Кэш привязывается к тегу co_purchases, что позволяет сбрасывать его при изменении заказов.
// component.php
if (!\Bitrix\Main\Loader::includeModule('iblock') || !\Bitrix\Main\Loader::includeModule('catalog')) {
return;
}
$productId = (int)$arParams['PRODUCT_ID'];
$limit = (int)($arParams['LIMIT'] ?? 8);
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache(3600, "co_purchases_{$productId}_{$limit}", '/co_purchases')) {
$arResult = $cache->getVars();
} elseif ($cache->startDataCache()) {
$cache->registerTag('co_purchases');
$recommendedIds = getFromCoPurchasesTable($productId, $limit);
$arResult = getProductsByIds($recommendedIds);
$cache->endDataCache($arResult);
}
$this->IncludeComponentTemplate();
Фильтрация и cold start
Перед отображением рекомендации проходят фильтр: только активные товары с ненулевым остатком. Если для товара мало данных (новый товар или магазин только запущен), используем content-based fallback — показываем товары из той же категории. Это решает проблему cold start.
function getRecommendations(int $productId, int $limit): array {
$coPurchases = getFromCoPurchasesTable($productId, $limit);
if (count($coPurchases) >= $limit) {
return $coPurchases;
}
$needed = $limit - count($coPurchases);
$exclude = array_merge([$productId], $coPurchases);
$categoryFill = getSameCategoryProducts($productId, $needed, $exclude);
return array_merge($coPurchases, $categoryFill);
}
Блок в корзине
Этот же механизм можно применить для корзины: показать «к товарам в вашей корзине часто покупают». Берём все товары из корзины, собираем их рекомендации, суммируем score и исключаем уже добавленные.
$basketItems = \Bitrix\Sale\Basket::loadItemsForFUser(\Bitrix\Sale\Fuser::getId());
$basketIds = [];
foreach ($basketItems as $item) {
$basketIds[] = $item->getProductId();
}
$allRecs = [];
foreach ($basketIds as $id) {
$recs = getFromCoPurchasesTable($id, 20);
foreach ($recs as $rec) {
$allRecs[$rec['recommended_id']] = ($allRecs[$rec['recommended_id']] ?? 0) + $rec['score'];
}
}
foreach ($basketIds as $id) unset($allRecs[$id]);
arsort($allRecs);
$topRecs = array_slice(array_keys($allRecs), 0, 8);
Почему совместные покупки эффективнее похожих товаров?
Сравнение подходов в таблице ниже. Блок совместных покупок опирается на реальное поведение покупателей, а не на формальные свойства. Мы гарантируем стабильную работу на любых версиях Битрикс (начиная с 17.0) и предоставляем гарантию на код.
| Метод | Источник | Конверсия | Производительность |
|---|---|---|---|
| Похожие по свойствам | Инфоблок | Средняя | Высокая |
| Совместные покупки (наш) | Заказы | Высокая (в 2-3 раза выше) | Средняя (с кешем) |
| Random | Нет | Низкая | Высокая |
Рекомендуем проводить A/B тест: на половине трафика показывать совместные покупки, на другой — стандартные рекомендации. В 80% проектов блок совместных покупок выигрывает по CTR на 30–50%.
Что входит в работу?
- Анализ текущих заказов и структуры данных
- SQL-запрос с оптимизацией под ваш объём
- Разработка агента предрасчёта
- Компонент с кешированием и fallback
- Интеграция блока в корзину
- Документация по развертыванию и настройке
- Консультации после релиза
Сроки разработки
| Этап | Срок |
|---|---|
| Анализ и проектирование | 1 день |
| SQL и агент | 2 дня |
| Компонент и кеширование | 2–3 дня |
| Fallback и холодный старт | 1 день |
| Интеграция в корзину | 1 день |
| Тестирование и документация | 2 дня |
| Итого | 1–1.5 недели |
Пример расчёта: при увеличении среднего чека на 20% дополнительная выручка с каждых 1000 посетителей существенно растёт. За год на трафике 10 000 посетителей в месяц это даёт значительный прирост.
Закажите разработку блока «с этим товаром покупают» — получите готовый компонент с документацией и консультацию после релиза. Свяжитесь с нами для оценки вашего проекта.







