Разработка сортировки товаров для интернет-магазина

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка сортировки товаров для интернет-магазина
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка сортировки товаров для интернет-магазина

Сортировка определяет, что пользователь видит в первую очередь. Дефолтная сортировка по дате добавления — не стратегия. Правильная сортировка по умолчанию увеличивает конверсию: вперёд выходят товары с высоким рейтингом, хорошими остатками и подходящей ценой. Каждый вариант сортировки — это запрос с разным ORDER BY, и каждый требует правильного индекса.

Стандартный набор вариантов

Вариант SQL Комментарий
Популярность ORDER BY sales_count DESC Требует отдельного счётчика
Рейтинг ORDER BY rating DESC, reviews_count DESC Двойная сортировка: рейтинг + вес
Цена: по возрастанию ORDER BY price ASC Базовый
Цена: по убыванию ORDER BY price DESC Базовый
Новинки ORDER BY created_at DESC По дате добавления
Акции ORDER BY discount_percent DESC Сначала самые выгодные
Релевантность По score поисковика Только в режиме поиска

Дефолтная сортировка — как правило, «Популярность» или кастомный «Рейтинг магазина» (ручная сортировка merchandise-менеджером).

Взвешенный рейтинг

Наивная сортировка по среднему рейтингу некорректна: товар с одним отзывом на 5 звёзд окажется выше товара с 200 отзывами на 4.8. Используем Bayesian average или формулу Wilson score:

-- Bayesian average: (C * m + sum_ratings) / (C + reviews_count)
-- C = prior weight (обычно среднее кол-во отзывов по каталогу)
-- m = prior mean (ожидаемый рейтинг без данных, обычно 3.0–3.5)

UPDATE products SET
  bayesian_rating = (50 * 3.5 + rating_sum) / (50 + reviews_count)
WHERE id = :id;

Это вычисляемое поле обновляется при каждом новом отзыве. Индекс по bayesian_rating для быстрой сортировки.

Счётчик продаж и популярности

sales_count — кумулятивный счётчик всех продаж с момента создания товара. Проблема: старый популярный товар всегда будет выше нового, который сейчас активно покупают.

Решение — time-decayed popularity score:

-- Обновляется ежедневно через cron
UPDATE products SET
  popularity_score = (
    SELECT SUM(quantity * EXP(-0.1 * EXTRACT(DAY FROM NOW() - o.created_at)))
    FROM order_items oi
    JOIN orders o ON oi.order_id = o.id
    WHERE oi.product_id = products.id
      AND o.created_at >= NOW() - INTERVAL '90 days'
  )

Коэффициент 0.1 настраивается: больше — сильнее обесцениваются старые продажи, меньше — дольше «помнит» историю. Для быстроменяющегося ассортимента (мода, сезонные товары) — больше. Для стабильных категорий (инструменты, бытовая техника) — меньше.

Ручная сортировка (merchandising)

Менеджер магазина хочет управлять тем, что видит пользователь в начале категории: продвигать новинки, спонсируемые товары, залежавшийся товар. Для этого нужен sort_order — ручное числовое поле.

Интерфейс: drag-and-drop список товаров в административном разделе категории. Технически — сохраняем массив product_id в упорядоченном виде или sort_order: integer на каждом товаре.

Гибридная сортировка: первые N позиций — ручные, остальные — по алгоритму.

ORDER BY
  CASE WHEN sort_order IS NOT NULL THEN 0 ELSE 1 END,  -- ручные первые
  sort_order ASC NULLS LAST,
  popularity_score DESC

Сортировка с Elasticsearch

При использовании Elasticsearch сортировка задаётся в параметре sort:

{
  "sort": [
    { "popularity_score": { "order": "desc" } },
    { "bayesian_rating": { "order": "desc" } },
    { "_score": { "order": "desc" } }
  ]
}

Для ручной сортировки: поле pinned_position с null для неприкреплённых. В ES есть специальный тип запроса pinned query — он поднимает конкретные ID в начало результатов без нарушения релевантности остальных.

Персонализированная сортировка

Продвинутый уровень — показывать каждому пользователю разный порядок на основе его истории. Пользователь часто покупает Apple — для него Apple-товары поднимаются выше. Пользователь смотрел товары в определённой ценовой категории — учитываем это.

Реализуется через пользовательские boost-факторы в Elasticsearch:

{
  "query": {
    "function_score": {
      "query": { "term": { "category_id": 14 } },
      "functions": [
        {
          "filter": { "term": { "brand": "apple" } },
          "weight": 2.0  // персональный boost для этого пользователя
        }
      ]
    }
  }
}

Boost-факторы вычисляются offline (батч-процесс на основе истории просмотров и покупок) и кешируются в Redis по user_id.

UI компонент сортировки

Стандартный select-дропдаун с вариантами. На мобайле — bottom sheet или отдельная страница (чтобы не мешать тапам). Текущий вариант сортировки отображается в URL (?sort=price_asc) и синхронизируется с состоянием компонента.

При изменении сортировки — запрос к API без перезагрузки страницы, скролл вверх к первому товару. Skeleton-плейсхолдеры пока список обновляется.

Индексы для производительности

-- Сортировка по цене
CREATE INDEX ON products (category_id, price ASC) WHERE status = 'active';
CREATE INDEX ON products (category_id, price DESC) WHERE status = 'active';

-- Сортировка по дате
CREATE INDEX ON products (category_id, created_at DESC) WHERE status = 'active';

-- Сортировка по рейтингу
CREATE INDEX ON products (category_id, bayesian_rating DESC) WHERE status = 'active';

-- Ручная сортировка + популярность (гибрид)
CREATE INDEX ON products (category_id, sort_order ASC NULLS LAST, popularity_score DESC);

Каждый дополнительный вариант сортировки — потенциальный отдельный индекс. При 8–10 вариантах сортировки это существенно влияет на размер индексов и скорость INSERT/UPDATE. Правильное решение: использовать ES для сложных сортировок, оставив в PostgreSQL только simple ORDER BY.

Сроки

  • Базовые сортировки (цена, дата, рейтинг, выбор в select): 2–4 рабочих дня
  • С взвешенным рейтингом и time-decayed popularity: 1 неделя
  • Ручная merchandising-сортировка с drag-and-drop интерфейсом: +1 неделя
  • Персонализация на основе истории пользователя: 2–3 недели (требует истории поведения и офлайн-расчётов)