AACsearch
Коннекторы и виджет

Маппинг полей коннектора

Поэтапный маппинг сущностей: товары, категории, варианты, цены, остатки, изображения и локали. Контракт каждого CMS-модуля при отправке данных в AACsearch.

Эта страница — окончательный справочник по тому, что CMS-модуль должен отправлять в AACsearch. Формы эндпоинтов — в Жизненном цикле Connector API; здесь — семантика: какое поле в CMS какому полю AACsearch соответствует и почему.

Каждый коннектор шлёт документы SyncProductInput. Форма умышленно узкая (это индекс товаров, а не общий контентный стор), но достаточно гибкая, чтобы через attributes хранить статьи, рецепты или любые другие сущности.

Поля товара

ПолеТипОбязательноЗамечания
external_idstringдаСтабильный первичный ключ платформы. Не slug, не SKU.
titlestringдаЧистый текст в настроенной locale. Стрипнуть HTML и шорткоды.
descriptionstringнетЧистый текст. Стрипнуть HTML, развернуть rich-text JSON / markdown.
skustringнетОсновной SKU или SKU дефолтного варианта.
brandstringнетИмя производителя / вендора. Пустая строка → удалить поле.
categoriesstring[]нетСм. Категории.
category_idsstring[]нетID категорий платформы для фильтров. Стабильные при переименовании.
tagsstring[]нетПлоский список ярлыков.
pricenumberнетОсновные единицы. См. Цены.
sale_pricenumberнетОсновные единицы. См. Цены.
currencystringнетISO 4217, 3 буквы в верхнем регистре. Нижний регистр валидатор не примет.
image_urlstring (URL)нетОсновное изображение. См. Изображения.
product_urlstring (URL)нетURL витрины — используется виджетом для перехода.
availabilityenumнет"in_stock", "out_of_stock", "preorder". См. Остатки.
stock_quantitynumberнетСумма доступных единиц по всем локациям.
attributesRecord<string,unknown>нетПроизвольные фасетные/display-поля. См. Атрибуты.
localeenumнетen, de, es, fr, ru. По документу на локаль.
created_atstring (ISO 8601)нетИспользуется для сортировки «Недавно добавлено».
updated_atstring (ISO 8601)нетПрименяется для детекции изменений в буфере; рекомендуется.

Правила external_id

Берите первичный ключ CMS:

  • WooCommerce / WordPress: post_id (число)
  • PrestaShop: id_product
  • Bitrix: iblock_element_id
  • Shopify: числовой product ID, не handle
  • Magento: entity_id, не SKU

Если платформа хранит локали как отдельные строки таблицы, добавьте суффикс локали: prod-123:en. Не переиспользуйте external_id между типами товаров и локалями — поиски схлопнутся.

Категории

Два поля, используются вместе:

  • categories — полный путь крошек, корень → лист, человекочитаемые строки. ["Обувь", "Беговая", "Трейл"], а не ["Трейл"]. Виджет рендерит путь в фильтрах.
  • category_ids — стабильные ID того же пути, корень → лист. Используется для фильтров, переживающих переименование категорий.

Если товар лежит в нескольких категориях, передавайте каждый путь отдельной строкой в categories. Порядок массива для ранкинга не важен — только идентичность строк для счётчиков фасетов.

CMSИсточник categoriesИсточник category_ids
PrestaShopps_category_lang.name по путиps_category.id_category по пути
Bitrixимена iblock-разделовID iblock-разделов
WordPressтермы таксономии «category»ID термов
Shopifyproduct_type + названия коллекцийID коллекций
Strapireference-поле, развёрнутое рекурсивноdocument-ID
Sanityreferences(), развёрнутые рекурсивно_id категорий

Варианты

Дефолтная модель — документы на уровне товара. Данные вариантов (размер, цвет, материал, SKU варианта, остатки по варианту) уезжают в attributes. Один товар = один документ.

Это правильный выбор для большинства e-commerce: покупатели ищут «синие беговые кроссовки», а не «синие беговые кроссовки размер 9.5 узкие». Виджет показывает карточку родительского товара; выбор варианта — на странице товара.

Когда отправлять документы на уровне вариантов

Стройте отдельный mapper, шлющий по документу на вариант, когда:

  • Поиск должен поднимать конкретные SKU (B2B-каталоги, магазины запчастей).
  • Заголовки или картинки вариантов сильно различаются (комплект vs одиночный товар).
  • Варианты живут в разных категориях.

В этом случае:

  • external_id — ID варианта с суффиксом родителя: prod-123:variant-7.
  • title включает атрибуты варианта: «Синие беговые кроссовки — размер 9.5 узкие».
  • image_url — картинка варианта, а не родителя.
  • Добавьте attributes.parent_external_id, чтобы дедуплицированный «по товару» поиск мог схлопывать результаты.

Эталонный Shopify-коннектор использует уровень товара по умолчанию; см. Custom Connector для варианта-mapper'а.

Цены

Формат на проводе

price и sale_price — это основные единицы, десятичные числа. 99.99 USD шлётся как 99.99, а не 9999. Connector API сам конвертирует в минорные единицы (kopecks-style BigInt) внутри ингест-пайплайна. Если отправить 9999, индексируется цена 9 999.00 USD.

Двухценовая модель

  • price — основная цена без активной акции.
  • sale_price — акционная цена, если активна. При заполненном sale_price виджет рендерит обе со страйком на price.

Когда цен много

В CMS с группами клиентов, B2B-тарифами и динамическим ценообразованием товар один, а цен много. Простая конвенция:

{
  "price": 99.99,
  "sale_price": 79.99,
  "currency": "USD",
  "attributes": {
    "price_by_group": {
      "retail": 99.99,
      "wholesale": 79.99,
      "vip": 69.99
    }
  }
}

price — дефолтная витринная цена. Остальные тарифы — в attributes.price_by_group. Витрина фильтрует или сортирует по нужной группе на стороне запроса.

Мультивалютные каталоги

Шлите валюту, которую видит клиент, в currency, остальные — в attributes.price_by_currency:

{
  "currency": "USD",
  "price": 99.99,
  "attributes": {
    "price_by_currency": { "EUR": 92.5, "GBP": 79.99 }
  }
}

AACsearch проиндексирует альтернативные цены как числовые атрибуты, и витрина сможет менять валюту без переиндексации.

Остатки

Два поля, которые виджет использует для бейджа доступности:

  • availability"in_stock" / "out_of_stock" / "preorder". Определяет бейдж на карточке.
  • stock_quantity — общее число единиц по локациям. Определяет подсказку «Осталось 3 штуки».

Правила маппинга

ПлатформаОткуда брать availability
PrestaShopps_stock_available.quantity > 0 AND политика out_of_stockin_stock
Bitrixхэндлер OnPriceUpdate; CATALOG_AVAILABLE = 'Y'in_stock
WooCommercepost meta _stock_status: instock / outofstock / onbackorder (→ preorder)
Shopifyсумма inventory_quantity по whitelist-локациям
Strapiкастомное поле content-type или значение по умолчанию in_stock

Товар «в наличии», если хотя бы одна whitelist-локация имеет количество > 0. Whitelist локаций настраивается в конфиге коннектора.

Backorder и pre-order

Если платформа поддерживает backorder или предзаказ, мапьте их в preorder. Виджет рендерит отдельный лейбл. Товар остаётся в результатах поиска — полезно для сценариев «скоро в продаже».

Изображения

image_url — это основное display-изображение, полный URL со схемой. Виджет рендерит его на карточке.

Если у товара несколько картинок, полный список — в attributes.images:

{
  "image_url": "https://cdn.example.com/products/brs-42/main.jpg",
  "attributes": {
    "images": [
      { "url": "https://cdn.example.com/products/brs-42/main.jpg", "alt": "Спереди" },
      { "url": "https://cdn.example.com/products/brs-42/side.jpg", "alt": "Сбоку" }
    ]
  }
}

Правила для картинок

  • Полные URL (https://...). Относительные ломаются, когда виджет работает на CDN edge.
  • Шлите версию того размера, что показывает витрина. AACsearch не ресайзит.
  • Если платформа отдаёт WebP / AVIF, шлите URL того формата, который реально использует витрина.
  • Пустая строка невалидна — удалите поле, если картинки нет.

Фолбэки изображений

Виджет рендерит плейсхолдер при отсутствии image_url. Если у вас плейсхолдеры по типу товара, настройте их через тему виджета, а не синтезируйте URL плейсхолдера на стороне коннектора.

Локали

AACsearch принимает пять локалей: en, de, es, fr, ru. Если в CMS есть локаль вне этого набора, шлите ближайшего соседа, а оригинальный код кладите в attributes.language:

{
  "locale": "en",
  "attributes": {
    "language": "pt-BR",
    "language_label": "Português (Brasil)"
  }
}

Разделение на документы

Для платформ с локализованными каталогами (Polylang, WPML, Shopify Markets, мультимагазин PrestaShop, i18n Strapi):

  • По документу на локаль на сущность.
  • external_id суффиксирован локалью: prod-123:en, prod-123:de.
  • Заголовок и описание — на языке локали.
  • Категории — тоже на языке локали, никогда не строками дефолтной локали.

Обновление одной локали не затрагивает документы других локалей. Обработчик событий должен слать только изменившуюся локаль.

Резолв локали на витрине

Виджет получает локаль с витрины — обычно из префикса URL (/en/, /ru/) или атрибута lang HTML. Виджет шлёт locale=<code> в каждом запросе, AACsearch фильтрует документы по полю locale. Документы без locale матчатся под все локали.

Атрибуты

Любое поле, которое фильтруется, фасетится или нужно только для отображения, уходит в attributes. Ключи произвольные; значения — примитивы или массивы примитивов.

Вывод типа

AACsearch выводит тип индекса из первого батча в свежем индексе:

Форма поляИндексируется как
"red" (string)facet, exact match
42 (number)numeric, sort + range
42.5 (number)float, sort + range
true (boolean)только filter
["red", "blue"] (array)multi-facet
[1, 2, 3] (массив чисел)не поддерживается — разделить или сплитить

Если поменять тип атрибута на лету (например, после 42 отправить "42"), AACsearch отбракует документ. Выбирайте тип на атрибут и не меняйте его.

Конвенции именования

  • Lowercase. Подчёркивания для разделения слов. option_color, не OptionColor.
  • Опции вариантов с префиксом option_: option_color, option_size. Виджет рендерит их в секции «Варианты» автоматически.
  • Производные поля — с префиксом домена: price_by_currency, price_by_group, stock_by_location.
  • Не занимайте имена верхнего уровня (из таблицы выше). Не кладите title в attributes.

Референсы по платформам

ПлатформаФайл маппера
PrestaShopmodules/prestashop/aacsearch/src/Exporter/
Bitrixmodules/bitrix/aac.search/lib/ProductExporter.php
WordPressmodules/wordpress/aacsearch-search/src/Mapper/
Shopifypackages/shopify-connector/src/product-mapper.ts
Strapipackages/strapi-plugin/src/server/services/aacsearch.ts

Читайте их как канонические примеры. Новые коннекторы должны следовать той же семантике полей — обратное отображение (CMS → SyncProductInput) платформо-специфично, но wire-формат инвариантен.

Связанные страницы

On this page