AACsearch
Аналитика

Запросы без результатов

Петля восстановления — детект нулевых запросов, закрытие gap-а синонимами / curations / контентом, измерение улучшения.

No-result-запрос — поиск, вернувший 0 хитов. Самое сигнальное событие в вашей аналитике: пользователь сказал точно, чего хотел, а вы сказали «у меня этого нет». Каждый такой запрос — либо relevance-промах (ответ есть, не нашли), либо content gap (нет ответа).

Это playbook по триажу.

Как фиксируются

Публичный поисковый handler пишет type: "zero_results" в SearchUsageEvent, когда found === 0. Top Queries показывает отдельный срез, дашборд — KPI-плитку no-results-rate.

Событие несёт:

  • Сырой query.
  • Активный filterBy (часто — причина нуля).
  • indexSlug.
  • locale.
  • searchTimeMs, чтобы отличать таймауты от настоящих пусто.

Чтение no-results-панели

const zr = await orpc.search.topQueries.call({
  organizationId,
  period: "30d",
  filter: { zeroResults: true },
  limit: 50,
});

Сортируйте по объёму. Топ-10–20 — это работы на эту неделю; хвост — backlog для контент-команды.

Три колонки вместе:

КолонкаСигнал
queryЛитеральная фраза пользователя.
searchesСколько разных сессий попали в пусто.
withFilterБыл ли активен filterBy — «ноль с фильтром» часто из-за фильтра, а не каталога.

iphone 15 с 200 zero-result-searches без фильтра — content gap. Тот же запрос с 200 zero и filterBy: "brand:=Samsung" — UX фильтров.

Триаж по шагам

По каждому топ-no-result, по порядку:

Шаг 1 — Опечатка или известный синоним?

Прогон в Search Preview. Если fuzzy сработал бы, но не сработал (typo-tolerance off, или запрос слишком длинный):

Шаг 2 — Реальный продукт/статья с vocabulary mismatch?

Ищите в каталоге напрямую (без запроса пользователя). Если нужный документ нашёлся — ответ был в индексе, слова пользователя его не дотянули:

  • Synonym mapping (например, "airpods" → "wireless earbuds").
  • Добавить альтернативный термин в tags / description документа.
  • Поднять вес соответствующего поля в queryBy.

Шаг 3 — Filter-induced ноль?

Если withFilter = true и базовый запрос матчится без фильтра:

  • Это UX. В клиенте детектите filter-induced-zero и показывайте «Clear filters to see X more results».
  • Долгосрочно: в виджете дизейблить фильтр-значения, дающие ноль при текущем запросе (graceful filter pruning).

Шаг 4 — Content gap?

Если ни synonym, ни filter-фикс не подошёл — у вас правда нет ответа. Это контент-команда:

  • Добавить недостающий продукт / статью.
  • Re-ingest.
  • Пометить запрос как «watched», чтобы измерять восстановление.

Измерение восстановления

После фикса смотрим тот же запрос в двух периодах:

const before = await orpc.search.topQueries.call({
  organizationId,
  period: "30d",
  offsetDays: 30,
  filter: { zeroResults: true },
});
const after = await orpc.search.topQueries.call({
  organizationId,
  period: "30d",
  filter: { zeroResults: true },
});

Успех — запрос уходит из zero-result-списка в «after». Не ушёл — фикс не прилетел: обычно reindex ещё не отработал или синоним был добавлен не в тот индекс.

KPI no-results-rate

Плитка в дашборде:

no-results rate = zero-result searches / total searches

Цель здорового storefront-а — < 5 %. > 10 % — серьёзный vocabulary mismatch. > 20 % — почти всегда баг в роутинге индекса.

Трекайте недельно. Резкий скачок обычно коррелирует с деплоем (новое поле схемы, новая локаль, новый коннектор) — bisect-те через Activity.

Bulk-паттерны

Для очень высокой кардинальности — построчно не разобраться. Два bulk-паттерна:

Кластер по токенам

Берёте топ-500 no-result, lowercase / tokenize, считаете самые частые общие токены. Кластер запросов с одним токеном ("airpods" в "airpods", "airpods pro", "new airpods") — один фикс (добавить термин) гасит кластер.

Кластер по brand / категории

Та же идея, но по фасетам. Если 200 zero-result-ов парсятся в «Brand: Acme, Category: phones» — у вас отсутствует продуктовая линейка.

Export отдаёт сырые строки; оба кластера — 20 строк скрипта.

Восстановление через AI fallback

Когда всё остальное не сработало — no-result-UX это естественная поверхность для fallback-а:

  • Гибридный semantic search, когда keyword вернул ноль.
  • Или AI answer поверх ближайших связанных товаров.

Не делайте дефолтом — оба добавляют латентность и стоимость — но на zero-ветке это оправдано, потому что альтернатива — ничего не показать.

Телеметрия по fallback-у

Если включаете AI fallback — инструментируйте:

trackEvent({
  type: "search_query",
  query,
  metadata: { fallback: "ai_answer", originalFound: 0 },
});

Тогда можно посчитать «AI fallback effectiveness» — как часто zero-result-сессия с fallback заканчивается кликом — и решить, оправдывает ли fallback себя.

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

On this page