Skip to content

Подборки и витрины через API ​

Иногда виджет не нужен — верстку страницы категории или лендинга магазин рисует сам, а от поиска нужна только выборка товаров под неё. Один запрос к поисковому API отдаёт готовый список — сортировку, карточки и разметку вы собираете на своей стороне.

Типичные сценарии:

  • топ товаров категории на странице этой категории (например, "хиты продаж" над обычным каталогом);
  • тематическая подборка на лендинге — "Распродажа", "Новинки недели";
  • блок "Товары со скидкой" на главной или в рассылке.

Во всех случаях используется тот же поисковый эндпоинт, что и виджет: разница только в том, что ответ рендерите вы сами, а не наш JS.

Как устроен запрос ​

POST {apiUrl}/api/v1/{projectId}/search
Content-Type: application/json

apiUrl — адрес API платформы, https://platform.searchforce.ru; projectId — идентификатор проекта из личного кабинета. Запрос публичный: авторизация не нужна, точку вызывает и виджет прямо из браузера покупателя (тот же принцип, что у /config — см. "Установку на сайт").

Формат запроса и ответа — Algolia-совместимый (см. "Итоговый документ → API поиска"). Из всего набора параметров для подборок обычно хватает пяти:

ПараметрЗначение
queryТекст запроса. Для подборки/витрины передавайте пустую строку — это выдача без текстового поиска, отбор идёт фильтрами.
facetFiltersФильтры вида ["поле:значение"]. Несколько значений одного поля во вложенном массиве — ИЛИ; отдельные элементы верхнего уровня — И.
numericFiltersЧисловые условия вида ["price>=1000", "price<=5000"].
hitsPerPageСколько позиций вернуть (см. "Ограничения" ниже).
sortByПорядок сортировки, например price:asc. Без него порядок не гарантирован — для подборки задавайте сортировку явно.

Строковый filters не поддерживается

В Algolia есть параметр filters со своим синтаксисом выражений — этот API его не принимает. Фильтры собираются только через facetFilters и numericFilters.

Полный список параметров запроса и полей ответа — в OpenAPI-спецификации платформы (/api/docs.json, схемы AlgoliaSearchParams и SingleSearchResponse).

Откуда брать имена фильтров ​

Имя поля в facetFilters — это имя фасета, как оно отдаётся поиску, а не название характеристики в фиде или в личном кабинете (например, характеристика "Цвет" может уйти в индекс как cvet). Список фасетов проекта с их именами:

  • в ответе GET {apiUrl}/api/v1/{projectId}/config, блок facets — там же человекочитаемая подпись (label) для каждого имени (name);
  • в личном кабинете, на странице проекта "Настройка выдачи" — то же самое, но глазами: колонка "Фильтр (фасет)" у полей и характеристик.

/config кэшируется на 10 минут (Cache-Control: public, max-age=600). Проверяя имя фасета сразу после того, как включили его в панели, добавьте ?preview=true, чтобы не упереться в кэш.

Вид значений в фильтре ​

У фасета, значениям которого фид задал вид (картинки-образцы, коды цвета), в /config заполнено поле visual:

json
{ "name": "cvet", "label": "Цвет", "type": "value", "search": "auto", "visual": "image" }
  • image — у значений есть картинки, color — коды цвета, null — обычный текстовый список.
  • Признак выводится из наличия данных, а не из настройки в кабинете: между включением настройки и ближайшим импортом его ещё нет. На это и рассчитывайте: visual отсутствует — рисуйте текст и за картинками не ходите.

Сами картинки отдаёт отдельный эндпоинт:

bash
curl "https://platform.searchforce.ru/api/v1/ВАШ-PROJECT-ID/facets/images?facet=cvet"
json
{
  "facet": "cvet",
  "mode": "map",
  "items": [
    { "value": "Мультикам", "image": "https://shop.ru/swatch/multicam.webp", "color": null, "count": 0 },
    { "value": "Айвори",    "image": null,                                   "color": "#f5f0e6", "count": 0 }
  ]
}
  • mode: "map" — вид пришёл из фида. mode: "representative" — у фасета своего вида нет, и эндпоинт вернул картинку самого популярного товара внутри каждого значения (этим режимом пользуются витрины категорий).
  • count в режиме map всегда 0: числа товаров живут в ответе /search и зависят от уже применённых фильтров, а карта вида их не знает.
  • Ответ описывает весь фасет, поэтому запрашивайте его один раз на фасет и кэшируйте у себя, а не на каждый ввод в строке поиска.

Что видит покупатель и как это настраивается со стороны каталога — «Вид значений в фильтре».

Ответ на /search содержит те же поля документа, что видит виджет — id/objectID, name, price, url, image_url, category_names и остальные, в зависимости от настроек проекта. Полный разбор полей — в "Итоговом документе".

Пример 1. Топ-N товаров категории ​

Категория товара доступна как готовый фасет category_names — тот же, по которому строит блок категорий автокомплит (см. "Autocomplete и полностраничный поиск"). Запрос без текста, фильтр по названию категории, нужное число позиций:

bash
curl -X POST https://platform.searchforce.ru/api/v1/ВАШ-PROJECT-ID/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "",
    "facetFilters": ["category_names:Юбки"],
    "hitsPerPage": 8,
    "sortBy": "price:desc"
  }'

Ответ:

json
{
  "hits": [
    {
      "objectID": "5652",
      "id": "5652",
      "name": "Юбка миди в клетку",
      "price": 4200.0,
      "url": "https://example.com/product/yubka-midi/",
      "image_url": "https://example.com/upload/iblock/105/105b68.jpg",
      "category_names": ["Юбки"]
    }
  ],
  "nbHits": 128,
  "page": 0,
  "nbPages": 16,
  "hitsPerPage": 8
}

hits — сама подборка в порядке, заданном sortBy (без него порядок не гарантирован); nbHits — сколько товаров всего подходит под фильтр, пригодится для ссылки "Смотреть все N товаров" на полную выдачу категории.

Если категорию можно выбрать не по названию, а по разделу, из которого пришёл запрос (страница категории и так знает свой раздел) — используйте то же значение, что показано в category_names товаров этого раздела, оно приходит из дерева категорий фида (см. "Каркас YML → дерево категорий").

Пример 2. Подборка по признаку — скидка, метка или свой фильтр ​

Готовый признак: товары со скидкой ​

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

bash
curl -X POST https://platform.searchforce.ru/api/v1/ВАШ-PROJECT-ID/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "",
    "facetFilters": ["has_discount:true"],
    "hitsPerPage": 12,
    "sortBy": "price:asc"
  }'

Так собирается блок "Товары со скидкой" без ручной подборки товаров.

Метки товаров: подборка, собранная руками в кабинете ​

Метка — это надпись, которую вы вешаете на товары сами: "Распродажа" на целую категорию до конца месяца, "Новинка" на десяток позиций. Метки настраиваются в разделе "Мерчандайзинг" личного кабинета и не требуют ничего от фида (как их заводить — в разделе "Метки товаров").

Все метки товара лежат в поле labels, и подборка по метке — обычный фильтр по нему:

bash
curl -X POST https://platform.searchforce.ru/api/v1/ВАШ-PROJECT-ID/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "",
    "facetFilters": ["labels:Распродажа"],
    "hitsPerPage": 24
  }'

Список меток, действующих у проекта прямо сейчас, отдаёт /config — блок labels. Ту же метку виджет рисует бейджем на карточке товара.

Кастомные фильтры: свои чекбоксы в панели фильтров ​

Кастомный фильтр — блок чекбоксов, который вы собираете сами: "Акции" с вариантами "Скидка" и "Уценка". Каждый вариант описывается условиями по полям и характеристикам каталога или просто списком товаров; настраивается всё там же, в разделе "Мерчандайзинг" (см. "Свои фильтры").

У фильтра своё поле в документе — cf_<имя>, а значения в нём — названия вариантов, под которые попал товар. Точное имя поля показано в форме фильтра ("Имя поля в API") и в /config, в блоке facets рядом с подписью:

bash
curl -X POST https://platform.searchforce.ru/api/v1/ВАШ-PROJECT-ID/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "",
    "facetFilters": ["cf_akcii:Скидка"],
    "hitsPerPage": 24
  }'

Имя поля не меняется, если вы переименуете фильтр в кабинете, — ссылки в вашем коде переживут правку подписи.

Метки и фильтры доезжают до товаров не мгновенно

Новая метка или новый вариант фильтра появляется на товарах в течение нескольких минут после сохранения: значения пересчитываются по всему каталогу фоном. Кастомный фильтр вдобавок ждёт обновления индекса — до этого момента его не будет ни в /config, ни в фильтрах виджета.

Метка со сроком действия снимается сама, но тоже не в ту же секунду: в течение часа после конца периода.

Снятая метка какое-то время ещё попадает в подборку

Поле товара очищается сразу, а вот поисковый индекс дочищает такие значения только при ближайшем полном обновлении каталога (как правило — очередной импорт фида). До этого момента запрос facetFilters: ["labels:Распродажа"] может вернуть товар, у которого метки уже нет; то же касается варианта кастомного фильтра, из которого товар выбыл.

Если для витрины это важно, берите список действующих прямо сейчас меток из /config (блок labels) и отфильтровывайте на своей стороне всё, чего в нём нет.

Признак из фида ​

Если признак уже есть в выгрузке, ничего настраивать в мерчандайзинге не нужно — достаточно включить характеристику как фильтр в "Настройка выдачи" (характеристике или полю — тумблер "Фильтр (фасет)"; см. "Характеристики <param> → Настройка в личном кабинете"). Изменение применяется автоматически, без переиндексации всего каталога — обычно занимает несколько минут; если характеристики ещё не было в фиде, дождитесь также ближайшего импорта фида (см. "Импорт и обновление").

Дальше — тот же принцип, что и с категорией: находите фактическое имя фасета в /config (характеристика "Акция" может уйти в индекс как akciya) и фильтруете по нему:

bash
curl -X POST https://platform.searchforce.ru/api/v1/ВАШ-PROJECT-ID/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "",
    "facetFilters": ["akciya:Распродажа"],
    "hitsPerPage": 24
  }'

Так же собираются подборки по любому другому фильтруемому признаку каталога — сезонная коллекция, бренд-партнёр и так далее: характеристика с ограниченным набором значений в фиде плюс включённый фильтр.

Ограничения и советы ​

  • Правила выдачи ("Мерчандайзинг": поднять, опустить, закрепить, скрыть — см. "Правила выдачи") переставляют только первые 250 результатов запроса — товары глубже они не достают (см. "Редактор виджета → Настройки сборки"). Для подборки, где важен порядок вручную заданных товаров, задавайте фильтр так, чтобы в него попадало не больше пары сотен позиций.
  • Правила с запросом-триггером (правило применяется только к конкретным поисковым фразам) на подборке с query: "" не сработают — сюда попадают только правила без условия по тексту запроса, действующие на любую выдачу.
  • "Поднять" и "опустить" работают только на сортировке по релевантности. Если в запросе передан sortBy по цене или по любому другому полю, порядок задаёте вы, и поднятие с опусканием не применяются. "Скрыть" и "закрепить" действуют всегда, при любой сортировке: первое убирает товар из выдачи, второе ставит его на заданное место.
  • Даты начала и конца действия правил и меток считаются по московскому времени: период, у которого конец — 30 сентября, действует до 30 сентября 23:59 по Москве.
  • hitsPerPage — не больше 250: это предел поискового движка. Нужна подборка длиннее — запрашивайте страницами через page, а не одним hitsPerPage.
  • Сортировка работает так же, как в виджете: по полю, у которого в настройках проекта включена "Сортировка" (см. "Характеристики <param> → Настройка в личном кабинете"). Актуальный список доступных значений sortBy — в /config, блок sort_options (поле value, например price:asc); значение не из списка поиск не примет.
  • Кэшируйте ответ на своей стороне на несколько минут и обновляйте по расписанию или по действию редактора, а не при каждом показе страницы покупателю — подборка на витрине не обязана быть актуальной с точностью до секунды, а лишний трафик впустую расходует ваш лимит запросов.