1. Обзор

Описание

Сервис Search DSL предоставляет высокоуровневый, удобный язык запросов (DSL) для фронтенд-разработчиков. Он абстрагирует сложность работы с исходными запросами Elasticsearch, обеспечивая единообразную, безопасную и поддерживаемую функциональность поиска на нескольких e-commerce сайтах.

Скоуп

  • Фронтенд: Используют DSL для поисковых запросов с помощью компактного REST/JSON API.
  • Бэкенд: Сервис преобразует кастомные DSL-запросы в запросы Elasticsearch и возвращает нормализованные результаты поиска.

Цели

  1. Единообразие: Обеспечить одно решение для поиска на нескольких платформах e-commerce.
  2. Поддерживаемость: Централизовать логику поиска для упрощения обновлений, расширений и исправлений ошибок.
  3. Удобство использования: Предоставить простую JSON-схему, чтобы разработчики не нуждались в знаниях Elasticsearch DSL или GraphQL.
  4. Мультисайтовость: Один сервис DSL для всех сайтов, идентифицируемый уникальным site_id.

2. Основные функции

  1. Высокоуровневые запросы DSL

    • Пользователи отправляют запросы поиска в JSON, с text (основной текстовый запрос), набором типизированных filters, а также limit/offset и сортировкой.

    • Пример:

      {
        "request": {
          "text": "Водонагреватель",
          "filters": [
            {
              "key": "category",
              "filter_type": "multi",
              "value": {
                "reference": [
                  "9f61a853-20d0-433a-9525-b2fe50fcfeb7"
                ]
              }
            },
            {
              "key": "price",
              "filter_type": "range",
              "value": {
                "range": {
                  "from": { "value": 100.0 },
                  "to": { "value": 300.0 }
                }
              }
            },
            {
              "key": "is_available",
              "filter_type": "bool",
              "value": {
                "bool": true
              }
            }
          ]
        },
        "limit": 10,
        "offset": 0,
        "sort": "relevance"
      }
       
    • Эта структура позволяет гибко расширять типы фильтров (мульти-выбор, диапазон, булевы значения и т. д.).

  2. Фильтрация

    • Каждый объект фильтра имеет:
      • ключ, например, "category", "price", "is_available"
      • индикатор типа фильтра (например, multi, range, bool)
      • значения (например, массив ссылок, числовой диапазон, булевы значения).
    • Сервис сопоставляет эти фильтры с соответствующими полями Elasticsearch. Например:
      • key: "category" может соответствовать полю category_id.
      • key: "price" может соответствовать числовому полю price.
      • key: "is_available" может быть булевым полем.
  3. Пагинация

    • Используйте limit (количество товаров на запрос) и offset (начальный индекс) для управления пагинацией.
    • Внутренне это переводится в from = offset и size = limit.
    • Пример: limit = 10, offset = 0 → первые 10 товаров.
  4. Сортировка

    • По релевантности (по умолчанию): Сортировка по тому, как хорошо результаты соответствуют запросу.
    • По цене (по возрастанию/убыванию): price_asc или price_desc
    • По имени (по возрастанию/убыванию): name_asc или name_desc
    • По рейтингу/популярности: rating_desc, popularity_desc (когда будут существовать рейтинги товаров или показатели популярности)
    • По дате (по новизне): date_desc, date_asc (когда будут доступны даты создания или выпуска товаров)
    • По пользовательским полям: например, sales_count_asc, sales_count_desc (в зависимости от доступных полей)
    • Фронтенд может передавать параметр sort, чтобы указать желаемый порядок.
    • Поле "sort" может быть чем-то вроде "relevance", "price_asc" и т. д.
    • Сервис сопоставляет их с сортировками ES. Например, "relevance"_score desc, "price_asc"price ascending.
  5. Фасетная навигация

    • Сервис может возвращать агрегированные данные (бренды, категории, ценовые диапазоны и т. д.) для панелей фильтров.
    • См. эндпоинт GET /facets.
  6. Автодополнение / предложения (опционально)

    • Предоставляет частичные совпадения/предложения по мере ввода пользователем.
  7. Безопасность / Ролевой доступ (опционально)

    • Некоторые сложные запросы или функции индексации могут быть ограничены для авторизованных ролей.
  8. Аналитика / Логирование (опционально)

    • Сбор данных о использовании запросов, популярных запросах или кликах по результатам для оптимизации.

3. API Эндпоинты

Примечание: Поскольку поддерживаются несколько сайтов электронной коммерции, каждый запрос должен указывать, на какой сайт нужно выполнить запрос, обычно через параметр site_id. Это можно указать как параметр запроса (/search?site_id=...) или внутри тела запроса.

3.1 POST /search

  • Описание: Основной эндпоинт для поиска товаров с использованием DSL.
  • Поддержка нескольких сайтов: Укажите site_id, чтобы запросить правильный индекс

Пример запроса

{
  "site_id": "1ab2c3d4-5678-90ef-1234-567890abcdef",
  "request": {
    "text": "Водонагреватель",
    "filters": [
      {
        "key": "category",
        "type": "filter_type_multi",
        "value": {
          "reference": [
            "9f61a853-20d0-433a-9525-b2fe50fcfeb7"
          ]
        }
      },
      {
        "key": "price",
        "type": "filter_type_range",
        "value": {
          "range": {
            "from": { "value": 100.0 },
            "to": { "value": 300.0 }
          }
        }
      },
      {
        "key": "is_available",
        "type": "filter_type_bool",
        "value": {
          "bool": true
        }
      }
    ]
  },
  "limit": 10,
  "offset": 0,
  "sort": "relevance"
}
 

Пример ответа

{
  "total": 42,
  "limit": 10,
  "offset": 0,
  "hits": [
    {
      "id": "abc123",
      "name": "Heater X",
      "price": 1999,
      "...": "другие поля..."
    },
    {
      "id": "def456",
      "name": "Heater Y",
      "price": 2999,
      "...": "другие поля..."
    }
    // ...другие товары...
  ]
}
 

Как получить все товары в категории

Для получения всех товаров в категории можно оставить пустое "text" и указать только фильтр по категории:

{
  "site_id": "1ab2c3d4-5678-90ef-1234-567890abcdef",
  "request": {
    "text": "",
    "filters": [
      {
        "key": "category",
        "type": "filter_type_multi",
        "value": {
          "reference": [
            "91d26ba4-ea09-4547-9e63-c4022a65d287"
          ]
        }
      }
    ]
  },
  "limit": 20,
  "offset": 0,
  "sort": "relevance"
}
 

Пример ответа

{
  "total": 42,
  "limit": 10,
  "offset": 0,
  "hits": [
    {
      "id": "abc123",
      "name": "Heater X",
      "price": 1999
      // ...другие поля...
    }
    // ...
  ]
}
 

3.2 GET /facets

  • Описание: Возвращает агрегированные данные для фасетного поиска (например, количество брендов, категорий, ценовых диапазонов и т. д.).
  • Поддержка нескольких сайтов: Укажите site_id как параметр запроса или заголовок.
  • Возможные параметры запроса:
    • site_id для указания, с данными какого сайта работать.
    • text (поисковый запрос, необязательно).
    • Можно передавать контекст фильтров, чтобы фасеты отражали текущие фильтры пользователя.

Пример: Получение фасетов для конкретного сайта с некоторыми фильтрами

GET /facets?site_id=1ab2c3d4-5678-90ef-1234-567890abcdef&text=Heater&category=91d26ba4-ea09-4547-9e63-c4022a65d287&price_from=100&price_to=500
 
  • Сервис будет учитывать эти параметры для формирования запросов и вернет фасеты, соответствующих поиску по “Обогреватель” в категории 91d26ba4-ea09-4547-9e63-c4022a65d287 и ценовом диапазоне 100-500.

  • Ответ (пример):

    {
      "brand": [
        { "key": "Electrolux", "count": 42 },
        { "key": "Philips", "count": 30 }
      ],
      "category": [
        { "key": "Heaters", "count": 50 },
        { "key": "Air Conditioners", "count": 10 }
      ],
      "price": [
        { "key": 0, "count": 5 },
        { "key": 500, "count": 8 }
        // ...
      ]
    }
     

Интеграция: вы получите фасеты, а затем сможете использовать их в массиве filters -> value -> reference в ваших запросах POST /search.

3.3 POST /autocomplete (Опционально)

  • Описание: Предоставляет suggestions (частичные совпадения) по мере ввода текста пользователем.

  • Поддержка нескольких сайтов: Укажите site_id в теле запроса или как параметр.

  • Тело запроса:

    {
      "site_id": "1ab2c3d4-5678-90ef-1234-567890abcdef",
      "partial": "электр"
    }
     
  • Ответ:

    {
      "suggestions": ["электролюкс", "электрообогреватель"]
    }
     

3.4 GET /health

  • Описание: Проверка состояния, чтобы подтвердить, что сервис работает.

3.5 POST /index (Только для администраторов)

  • Описание: индексация данных в Elasticsearch (ограничено для авторизованных пользователей или ролей).
  • Поддержка нескольких сайтов: Укажите site_id

4. Схема базы данных

В основном используется индекс Elasticsearch и возможно минимальные реляционные данные для аналитики или логов.

В этом разделе необходимо будет разместить ссылки на схемы индексов ES

  1. Маппинги Elasticsearch
    • Пример полей:
      • id, name, full_name (текст + подполе keyword)
      • brand.name (текст + keyword)
      • price (число)
      • categories (вложенные или массив строк)
  2. Опциональная реляционная база данных
    • Может хранить логи, аналитику поиска или бизнес-данные, не подходящие для Elasticsearch.

5. Пожелания по Дизайну

  1. Масштабируемость
    • Сервис должен масштабироваться горизонтально, возможно, с балансировщиком нагрузки.
  2. Безопасность
    • только сервис DSL, а не сам Elasticsearch, выставляется наружу.
    • Использование API ключей или токенов для публичного доступа.
  3. Производительность и кэширование
    • Кэширование часто запрашиваемых фасетов или запросов.
    • Использование doc-value полей для числовой сортировки или агрегаций.
  4. Поддержка синонимов и нечетких совпадений
    • Реализация анализаторов или логики нечеткого совпадения для удобного поиска.
  5. Ролевой доступ
    • Возможность ограничить индексацию или сложные запросы для некоторых ролей.

6. Будущие улучшения

  1. Продвинутая сортировка
    • Взвешенная или на основе машинного обучения сортировка для улучшения релевантности.
  2. Рекомендательная система
    • “Другие товары, которые могут вас заинтересовать” или персонализированные предложения.
  3. Аналитика и отчеты
    • Отслеживание запросов, которые не дали результат, популярных запросов или поведения пользователей.
  4. Правила мерчандайзинга
    • Ручная настройка приоритетов, специальные акции, приоритет по наличию.