Коннекторы и переиндексация
Загрузка документов из sitemap, URL, JSON и CSV по расписанию и перестройка индекса при изменении схемы без падения запросов.
Индекс поддерживают в актуальном состоянии две операции: коннекторы приносят документы извне, переиндексация перестраивает коллекцию, когда меняется схема, а не содержимое.
Коннекторы
Коннектор — это сохранённый источник плюс отображение полей. Настраивается в консоли (Search → Connectors) и запускается вручную или по интервалу. Типов четыре:
| Тип | Что читает | Типичное применение |
|---|---|---|
sitemap | sitemap.xml, затем каждую страницу | Документация и сайты |
url | Одну страницу | Лендинг или страница, которую ведут руками |
json | JSON, массив по пути rootField | Headless CMS, выгрузка товаров |
csv | Текст с разделителями | Каталоги, выгрузки из таблиц |
Настройки
| Ключ | Для чего | Комментарий |
|---|---|---|
url | все | Только http(s); размер ответа по умолчанию до 5 МБ |
rootField | json | Путь к массиву, например data.items |
idField, titleField, contentField, urlField, tagsField | json, csv | Отображение полей в структуру документа |
delimiter | csv | По умолчанию , |
maxDocuments | все | Жёсткий потолок на запуск, по умолчанию 500 |
defaults | все | Статические поля, добавляемые в каждый документ |
extractText | sitemap, url | Удалять HTML до индексации |
Каждый импортированный документ получает source_type равный типу коннектора, поэтому неудачный запуск легко откатить:
curl -sS -X DELETE "$AAC_API/indexes/documentation/documents" \
-H "Authorization: Bearer $AAC_KEY" \
-G --data-urlencode "filter_by=source_type:=sitemap"Защитные механизмы
- Защита от SSRF. URL коннектора разрешается до загрузки; loopback, link-local, приватные диапазоны и адреса метаданных отклоняются, в том числе IPv6-формы со встроенным таким IPv4, а соединение идёт именно на проверенный адрес (DNS rebinding не проходит). Каждый редирект проверяется заново; учётные данные (
Authorization, cookie, секретные заголовки коннектора) после редиректа на другой origin не отправляются.SEARCH_ALLOW_PRIVATE_URLS=trueотключает проверку адреса для локальной разработки; в production флаг игнорируется. - Секреты привязаны к адресу. Сохранённые секреты показываются как
***и хранятся зашифрованными. При смене URL, домена или хоста коннектора секреты нужно ввести заново (CREDENTIALS_REQUIRED), чтобы сохранённый пароль не ушёл на новый хост. Зашифрованное значениеenc:…, вставленное как секрет, отклоняется (INVALID_SECRET_VALUE). - Контрольные суммы. Содержимое каждого документа хешируется и сравнивается с сохранённым хешем, поэтому ночной запуск переимпортирует только изменившееся — разница между 40 000 записей и 40.
- Отказ по документу. Документ, который движок не принял, попадает в очередь мёртвых писем, а не обрывает запуск.
- Ограничения.
maxDocumentsограничивает запуск, лимит 5 МБ — память.
Мёртвые письма
Отклонённые документы сохраняются вместе с исходной нагрузкой и сообщением движка. После исправления отображения или схемы их можно повторить из консоли; очередь видна и в админ-панели по всем тенантам. Растущая очередь — самый ранний сигнал, что источник изменил форму, ещё до изменения доли пустых выдач.
Запуск задач
Планировщик выполняет коннекторы, агрегацию аналитики, ретенцию и снимки. Чтобы запустить цикл немедленно — из CI или из внешнего воркера в развёртывании без внутреннего таймера, — используйте админ-эндпоинт. Это операция оператора платформы: кроме API-ключа нужен заголовок x-platform-admin-token со значением SEARCH_PLATFORM_ADMIN_TOKEN развёртывания (иначе 403):
curl -sS -X POST "$AAC_API/admin/jobs/run?job=connectors" \
-H "Authorization: Bearer $AAC_KEY" \
-H "x-platform-admin-token: $AAC_PLATFORM_ADMIN_TOKEN"{
"job": "connectors",
"result": { "connectors": "ok" },
"request_id": "req_5b7d9f1a3c5e7b9d1f3a5c7e"
}job принимает connectors, rollup, retention, snapshot, graph или all. Любое другое значение — 422 INVALID_QUERY с сообщением job must be connectors|rollup|retention|snapshot|graph|all. Запуск пишется в журнал аудита. В result ключи соответствуют выполненной работе: connectors в том же цикле удаляет документы с истёкшим expires_at, rollup сообщает, сколько строк агрегировал, retention — сколько удалил, snapshot — статус резервной копии движка.
Переиндексация
Поисковый сервис не умеет удалять или менять тип поля на месте, а некоторые настройки принимаются только при создании. Такие изменения требуют перестройки. POST /indexes/{slug}/reindex делает это без простоя:
- Создаётся теневая коллекция
<alias>_v<n+1>с текущей схемой и настройками. - Документы переливаются из живой коллекции в теневую.
- Синонимы и курирование воспроизводятся на теневой коллекции.
- Алиас атомарно переключается.
- Старая коллекция сохраняется как коллекция отката задачи (планировщик удаляет её через
SEARCH_ROLLBACK_RETENTION_DAYS, по умолчанию 7 дней), а строкаSearchSchemaMigrationфиксирует произошедшее.
Поиск идёт через алиас, поэтому окна, в котором запрос видит полузаполненную коллекцию, не существует: текущие запросы обслуживает старая коллекция до самого переключения.
curl -sS -X POST "$AAC_API/indexes/documentation/reindex" \
-H "Authorization: Bearer $AAC_KEY"{
"index": "documentation",
"job_id": "job_01HZYC4M",
"status": "queued",
"status_url": "/api/v1/jobs/job_01HZYC4M",
"request_id": "req_2f4a6c8e0b2d4f6a8c0e2b4d"
}Ответ — 202 Accepted: перестройка идёт фоновой задачей. Опрашивайте GET /jobs/{jobId} (см. Задачи): там phase, progress, а после completed — result.documents и result.duration_ms. Повторный reindex того же индекса, пока активен первый, — 409 JOB_CONFLICT.
Требования и ограничения
- Право
settings:write. - Функция тарифа
reindex: на Free её нет, на Pro и Enterprise есть. - Операция выполняется задачей планировщика, а не внутри HTTP-запроса. Если воркер упал, задача подхватывается снова после истечения lease.
?sync=trueблокирует запрос до конца перестройки и предназначен только для тестов. - Документы берутся из живой коллекции движка, а не из Postgres, поэтому всё, что проиндексировано в обход платформы, сохраняется.
Когда нужна переиндексация
| Изменение | Переиндексация? |
|---|---|
| Добавление поля | Нет — аддитивные поля применяются к живой коллекции |
| Новый синоним или правило курирования | Нет — применяется сразу |
Изменение num_typos, весов, фасетов | Нет — это время запроса |
| Удаление поля, смена типа | Да |
| Смена разделителей токенов, стоп-слов, вложенных полей | Да — настройки времени создания |
Смена модели эмбеддингов или полей from | Да — векторы считаются при записи |
| Переход на другую размерность вектора | Да |
Проверка результата
curl -sS "$AAC_API/indexes/documentation/stats" -H "Authorization: Bearer $AAC_KEY"Сравните documents с числом до переиндексации и посмотрите на queries_24h и avg_latency_24h_ms на предмет регрессии. Пословный diff доступен в представлении схемы консоли: оно показывает поля живой коллекции так, как их отдаёт движок.
A/B-эксперименты
Поисковые эксперименты делят живой трафик между двумя профилями поиска с закреплением за посетителем, показывают клики и uplift и позволяют принять или откатить победителя. Также описано старое разделение через settings.abTest.
Квоты и биллинг
Что считается единицей, как блоки списываются с кошелька и как увидеть расход до того, как лимит превратится в 429.