Create Your First Index
Create a search index, understand the collection-alias model, and run your first search query through the dashboard.
A search index in AACsearch maps to a search index with versioned naming and an alias. Creating an index provisions the search index and registers the index in the database.
What is an index?
Each index represents a searchable catalog — typically one per store or product set.
Organization
└── SearchIndex (slug: "products")
collectionName: "org123_products_v1" ← search index (versioned)
aliasName: "org123_products" ← search alias (stable, always points to current)All search queries target the alias, not the versioned collection directly. This allows zero-downtime reindex — a new version is built while the current version serves traffic, then the alias is atomically swapped.
Create an index via the dashboard
- Open the SaaS dashboard at
http://localhost:3000 - Select your organization from the switcher
- Navigate to Search → Indexes
- Click Create index
- Enter a slug (e.g.,
products) and optional display name - Click Create
The dashboard calls searchRouter.createIndex which provisions the search index
and creates the SearchIndex row in Postgres.
Create an index via oRPC
import { orpc } from "@shared/lib/orpc-query-utils";
const index = await orpc.search.createIndex.call({
organizationId: "org_...",
slug: "products",
name: "Product catalog",
});Default collection schema
When an index is created, AACsearch provisions a search index with a product-optimized schema:
{
"fields": [
{ "name": "id", "type": "string" },
{ "name": "title", "type": "string", "weight": 10 },
{ "name": "sku", "type": "string", "weight": 8 },
{ "name": "brand", "type": "string", "weight": 5, "facet": true },
{ "name": "categories", "type": "string[]", "weight": 5, "facet": true },
{ "name": "description", "type": "string", "weight": 2 },
{ "name": "price", "type": "float", "facet": true },
{ "name": "sale_price", "type": "float", "optional": true },
{ "name": "availability", "type": "string", "facet": true },
{ "name": "locale", "type": "string", "facet": true },
{ "name": "created_at", "type": "int64" }
],
"default_sorting_field": "_text_match"
}The schema is defined in packages/search/lib/collections.ts and evolves with the product schema version.
Ingest your first document
Once the index is created, push a document through the ingest buffer:
const result = await orpc.search.upsertDocument.call({
organizationId: "org_...",
indexSlug: "products",
document: {
id: "product-123",
title: "Wireless Headphones",
sku: "WH-2024",
brand: "Acme",
categories: ["Electronics", "Audio"],
description: "Noise-cancelling over-ear headphones with 30h battery.",
price: 99.99,
availability: "in_stock",
locale: "en",
created_at: Math.floor(Date.now() / 1000),
},
});This calls enqueueManySearchIngest() which writes to SearchIngestBuffer. The background worker
picks it up and forwards to AACSearch within seconds.
Run a search query
Use the Search Preview tab in the dashboard, or call the public search endpoint directly:
curl -X POST https://your-app.com/api/search \
-H "Authorization: Bearer ss_search_your_key" \
-H "Content-Type: application/json" \
-d '{
"indexSlug": "products",
"q": "headphones",
"queryBy": "title,description,brand",
"page": 1,
"perPage": 10
}'See Public Search Endpoint for the full request schema.
What happens after index creation
- The dashboard Getting Started checklist updates to mark "Create index" as complete
- The Import Jobs tab becomes available for bulk CSV/JSON import
- The API Keys tab shows the index-scoped key panel
- The Widget tab shows the install snippet pre-filled with the index slug
Next steps
- API Keys — generate keys for your integration
- Ingest and Reindex — bulk import and schema updates
- Connector Onboarding — connect a CMS for automatic sync