AACSearch

Reindexing

Rebuild an index when the schema changes, without dropping a query — and understand exactly what a rebuild does and does not fix.

Reindexing rebuilds the whole collection. You need it when the shape of your data changes, not the data itself: a new field, a changed type, a switch in facet, sort or tokenization. Content updates do not need a reindex — those go through delta sync.

Why queries keep working during a rebuild

Search never reads a collection directly. It reads an alias, and the alias points at a versioned collection:

aacsearch_org123_products        ← alias, what every query uses
    └─ aacsearch_org123_products_v3   ← live collection

A reindex builds _v4 next to _v3. Only when _v4 is completely filled, and synonyms and curations are replayed into it, does the alias move. The swap is a single metadata operation, so there is no window where a query hits a half-filled collection.

Running a reindex

curl -sS -X POST "$AAC_API/indexes/products/reindex" \
  -H "Authorization: Bearer $AAC_KEY"

No request body. The call answers 202 Accepted at once and queues a reindex job; a scheduler worker runs the rebuild under a lease, so no HTTP request is held open:

{
	"index": "products",
	"job_id": "clx8f2...",
	"status": "queued",
	"status_url": "/api/v1/jobs/clx8f2...",
	"request_id": "req_..."
}

Poll the job until status is completed:

curl -sS "$AAC_API/jobs/clx8f2..." -H "Authorization: Bearer $AAC_KEY" | jq '.job | {status, phase, progress, result}'

The finished job's result holds documents (written into the new collection) and duration_ms. A second reindex while a reindex or a snapshot restore is queued or running answers 409 JOB_CONFLICT with the active job_id. DELETE /jobs/{jobId} cancels a rebuild that has not reached the alias swap.

?sync=true keeps the old blocking call that answers 200 with { index, job_id, documents, duration_ms }. It exists for test suites only, and it is subject to the same 409 JOB_CONFLICT check. A rebuild only replaces the target index's live collection; other indexes in the organization are untouched.

Requirements

RequirementWhy
Key with settings:writeA reindex changes collection metadata
Plan feature reindexMetered on Free
Rate limit headroomReindex is rate-limited — it must not be triggered in a loop

Phases

The job reports phase and progress while it runs:

PhaseProgressWhat is happening
queued0Waiting for a worker
loading10Job claimed; new collection being created
copying15 → 88Documents written into the new collection, synonyms and curations replayed
swapping90Alias being repointed — the job can no longer be cancelled
done100status is completed

If the job fails the alias does not move — old data keeps serving. A failed reindex loses nothing: a collection that an alias serves is never dropped by a failed or cancelled build. If the worker process dies mid-build, the lease expires, the job is claimed again and the abandoned shadow collection is dropped.

Writes that arrive during the build are not lost: right before the swap, the documents written or changed since the build started, and the documents deleted meanwhile, are applied to the new collection. Server signals (_popularity, graph_*) are copied over from the live collection.

Progress is visible through GET /jobs/{jobId} and in the console (Sync).

Where the documents come from

The build reads from the document mirror — search_document.payload, the copy of every document kept in the database. Two consequences matter:

  • a schema change does not mean re-crawling your source;
  • if your CMS is down, the rebuild still runs.

Legacy rows written before the mirror existed have no payload. Those are copied from the live collection instead, so a mixed index loses nothing.

Rollback

The previous collection is kept after the swap rather than deleted immediately — a rebuild that imports fine can still produce a worse index.

Note: the rollback endpoint is not exposed yet. It is planned on the API surface; until it ships, treat a reindex as one-way and verify the result before running it on production. A retained collection can be repointed manually by support.

This limitation is deliberate to document rather than hide: an index that cannot be rolled back should not be rebuilt on a Friday.

What gets carried over

ItemBehaviour
DocumentsRebuilt from the mirror
SynonymsReplayed after indexing
CurationsReplayed, including pins
RulesStored in the database, unaffected
Analytics and clicksStored per index, unaffected
API keysStored per organisation, unaffected

Cost

A reindex writes every document once. On a metered plan that counts once against your write quota — the same as re-uploading everything, but without downtime.

DocumentsTypical duration
10 000seconds
100 000a few minutes
1 000 000under an hour

When a reindex is not needed

ChangeReindex?Instead
Document contentNoDelta sync
Add an optional fieldNoSchema evolution
Add a field with a defaultNoSchema evolution
Change a field typeYes—
Turn facet on or offYes—
Change tokenization or stemmingYes—
Delete a fieldYes—

If you only add fields, use schema evolution: it validates the change against the live collection and skips the rebuild entirely.

Verifying the result

curl -sS "$AAC_API/indexes/products" \
  -H "Authorization: Bearer $AAC_KEY" \
  | jq '{collection: .collectionName, alias: .aliasName, version: .schemaVersion}'

aliasName keeps its value after a reindex — that is the point. schemaVersion increments. If a query behaves oddly after a swap, compare document counts before assuming a relevance problem:

curl -sS "$AAC_API/indexes/products/documents?per_page=1" \
  -H "Authorization: Bearer $AAC_KEY" | jq '.total'

A count that dropped between versions means the source was incomplete at build time. Rebuild rather than debug relevance.

On this page