Настройка персонализированных рекомендаций на основе поведения 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка персонализированных рекомендаций на основе поведения 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • 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
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка персонализированных рекомендаций на основе поведения 1С-Битрикс

Персонализированные рекомендации на основе поведения — это средний уровень между «похожими по категории» и полноценным ML. Не нужна отдельная Python-инфраструктура: всё строится на данных из базы Битрикса и нескольких SQL-запросах. Работает хуже нейросетей, но в разы лучше простых «похожих товаров» и требует только PHP + PostgreSQL.

Поведенческие сигналы и их веса

Разные действия пользователя имеют разную ценность как сигнал интереса. Типичная шкала:

Событие Вес
Покупка товара 10
Добавление в корзину 5
Добавление в избранное 4
Просмотр карточки (>30 сек) 2
Просмотр карточки (<30 сек) 1
Поисковый запрос с переходом 3

Веса хранятся в конфигурации, события — в таблице b_user_behavior (структура описана в статье о персонализации контента). Ключевое поле: EVENT_TYPE с значениями purchase, cart_add, wishlist, view.

Item-based коллаборативная фильтрация без ML

Суть: «пользователи, которые смотрели товар A, также смотрели товары B, C, D». Это считается напрямую из базы без ML-модели:

SELECT
    b2.ENTITY_ID AS recommended_id,
    COUNT(DISTINCT b2.USER_ID) AS co_view_count
FROM b_user_behavior b1
JOIN b_user_behavior b2
    ON b1.USER_ID = b2.USER_ID
    AND b1.ENTITY_ID != b2.ENTITY_ID
    AND b2.EVENT_TYPE IN ('view', 'cart_add', 'purchase')
    AND b2.DATE_CREATE > NOW() - INTERVAL '60 days'
WHERE
    b1.ENTITY_ID = :current_item_id
    AND b1.EVENT_TYPE IN ('view', 'cart_add', 'purchase')
GROUP BY b2.ENTITY_ID
ORDER BY co_view_count DESC
LIMIT 20;

Этот запрос выполняется офлайн (раз в час через агент) и результат кешируется в отдельной таблице:

CREATE TABLE b_item_recommendations (
    ITEM_ID          INT NOT NULL,
    RECOMMENDED_ID   INT NOT NULL,
    SCORE            FLOAT NOT NULL,
    UPDATED_AT       TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY (ITEM_ID, RECOMMENDED_ID)
);
CREATE INDEX idx_item_recs_item ON b_item_recommendations(ITEM_ID, SCORE DESC);

Персональный рейтинг для конкретного пользователя

Из 20 кандидатов-рекомендаций нужно выбрать 6–8 наиболее релевантных для текущего пользователя. Используем его поведенческий профиль:

function getPersonalizedRecs(int $itemId, int $userId, int $limit = 8): array {
    // 1. Получить кандидатов из item-based таблицы
    $candidates = getCandidates($itemId, 20);

    if (empty($candidates) || !$userId) {
        return array_slice($candidates, 0, $limit);
    }

    // 2. Получить категории из истории пользователя
    $userCategoryIds = getUserTopCategories($userId, 10);

    // 3. Boosting: поднять товары из предпочитаемых категорий
    foreach ($candidates as &$candidate) {
        $sectionId = getElementSectionId($candidate['id']);
        if (in_array($sectionId, $userCategoryIds)) {
            $candidate['score'] *= 1.5;
        }
    }

    // 4. Убрать уже купленные товары
    $purchased = getUserPurchasedIds($userId);
    $candidates = array_filter($candidates,
        fn($c) => !in_array($c['id'], $purchased)
    );

    usort($candidates, fn($a, $b) => $b['score'] <=> $a['score']);
    return array_column(array_slice($candidates, 0, $limit), 'id');
}

Кеширование и отображение

Кастомный компонент local:catalog.recommendations принимает ELEMENT_ID и выводит рекомендованные товары. Кеш строится на уровне item_id — не персональный, а item-based (одинаковые кандидаты для всех). Персональный буст применяется через отдельный AJAX-вызов после загрузки основного блока.

Такой подход позволяет кешировать основной блок рекомендаций на уровне Битрикса и при этом показывать каждому пользователю персонализированный порядок без лишних запросов к базе при рендеринге страницы.

Перенос истории при авторизации

Битрикс не переносит поведенческую историю анонима на авторизованного пользователя автоматически. Обработчик OnAfterUserLogin:

AddEventHandler('main', 'OnAfterUserLogin', function($fields) {
    $fuserId = \CSaleUser::GetAnonymousUserID();
    if (!$fuserId) return;

    $DB->Query("
        UPDATE b_user_behavior SET USER_ID = " . (int)$fields['USER_ID'] . "
        WHERE SESSION_ID = '" . $DB->ForSql(session_id()) . "'
          AND USER_ID IS NULL
    ");
});