AACsearch
Аналитика

Аналитика запросов

Популярные запросы, low-CTR, reformulations — как их читать, чтобы тюнить relevance.

Таб запросов — то, где большинство команд проводят основное время аналитики. Он отвечает на что ищут и сработали ли результаты, и комбинация этих ответов решает большинство вопросов о качестве поиска.

Что фиксируется по каждому запросу

Каждый публичный поиск (/api/search, /api/search/multi) пишет строку SearchUsageEvent с type: "search_query" и metadata, где:

  • Нормализованный запрос (lowercased, обрезанный).
  • found (кол-во результатов).
  • Латентность в мс.
  • Filter-выражение (если было).
  • sessionId и опциональный anonymousUserId для группировки.
  • queryId — server-id, связывающий последующие клики с этим поиском.

Click-события (type: "result_click") несут queryId обратно, чтобы CTR per query считался без джойнов.

Популярные запросы (Top Queries)

Top Queries сортирует запросы по объёму за период:

const top = await orpc.search.topQueries.call({
  organizationId,
  period: "30d",
  limit: 10,
});

Возвращает:

Array<{
  query: string;
  searches: number;
  clicks: number;
  ctr: number;           // clicks / searches
  resultsFound: number;  // среднее за период
  zeroResults: boolean;  // true, если средний found = 0
}>

Как читать:

  • Объём + высокий CTR. Работает. Не тюньте.
  • Объём + CTR < ~10%. Кандидаты на relevance — смотрите Relevance tuning.
  • Объём + zero results. Gap в контенте — No-results.
  • Объём + медленная латентность. Производительность — Operations / Performance.

В дашборде ограничьте топ-10; больше — через API.

Low-CTR-запросы

Тот же срез, но по наименьшему CTR при ≥ N searches (default: 5 searches на период). Это запросы, где есть демонстрированный спрос, но список результатов не убеждает.

const lowCtr = await orpc.search.topQueries.call({
  organizationId,
  period: "30d",
  limit: 50,
  minSearches: 5,
  orderBy: "ctr_asc",
});

Двухшаговый playbook:

  1. Прогоните запрос в Search Preview. Гляньте топ-10. Если нужного продукта нет — retrieval ломается; правим веса queryBy или добавляем синоним.
  2. Если нужный есть, но не наверху. Pin-curation на этом запросе.

Для high-volume / low-CTR, которые упираются — пересмотрите поверхность: возможно, нужен AI answer или federated multi-search.

Reformulations

Reformulation — пользователь запустил A, посмотрел результаты, тут же запустил B (в том же sessionId, обычно в 30 секундах). Сигнал: A не подошёл, B — настоящий intent.

Дашборд показывает топ пар:

OriginalReformulationSessions
running shoesnike running shoes142
tvoled tv89
phone caseiphone 15 case73

Reformulations — бесплатный поиск синонимов. Когда «running shoes» → «nike running shoes» — частая пара, бренд имплицитен в широком запросе; возможно, надо поднять вес brand в queryBy.

Чтобы дёрнуть:

const reform = await orpc.search.analyticsEvents.call({
  organizationId,
  period: "30d",
  type: "search_query",
  groupBySession: true,
});
// Постобработка: соседние строки в одной сессии.

Чтение по локалям

При мульти-локальном каталоге читайте с группировкой по metadata.locale. Запрос с большим объёмом в одной локали и пустой в другой — это translation/routing-проблема, не relevance.

То же для metadata.indexSlug — дашборд по умолчанию даёт org-wide, но per-index drill-down часто показывает другие паттерны.

Длина и форма запроса

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

  • Медианная длина. Тренд в сторону длинных запросов часто значит, что пользователи устали от коротких ключевиков и пробуют предложения. Сигнал — включить Semantic search hybrid.
  • Wildcard / browse rate. Запросы с q: "*" (browse с фильтрами) vs full-text. Перевес * — либо здоровая UX фильтров, либо недоверие к поисковой строке.

Оба извлекаются из сырых event metadata через analyticsEvents.

Сравнение периодов

Дашборд показывает один период. Для period-over-period — два окна и diff на клиенте:

const [a, b] = await Promise.all([
  orpc.search.topQueries.call({ organizationId, period: "30d", limit: 200 }),
  orpc.search.topQueries.call({ organizationId, period: "30d", offsetDays: 30, limit: 200 }),
]);

// Дельта per query.

offsetDays сдвигает окно назад. Удобно ловить drift после деплоя.

Кэш и пагинация topQueries

topQueries использует per-org-кэш с TTL ~5 минут. Дашборд обновляет по кнопке; программные callers пусть кэшируют так же (агрегация по SearchUsageEvent затратна на крупных тенантах).

Пагинация — offset. Для пуллов > 1000 строк — Export.

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

On this page