AI Semantic Search
AI Semantic Search adds meaning-aware (vector) search on top of keyword search, per index. Results blend both — a search for "keep my coffee hot on the summit" can surface a vacuum flask whose product copy never contains those words, because the embedding model understands they mean the same thing.
Under the hood, CelerSearch configures a Meilisearch embedder (an embedding model connection) on the index and sends hybrid search parameters with every query.

Requirements
- Meilisearch 1.13 or newer — embedders are GA, nothing to enable.
- Meilisearch 1.3 – 1.12 — embedders exist behind the
vectorStoreexperimental flag, which must be enabled on the instance.
When the bound engine doesn't qualify, the section renders a locked panel explaining the requirement, with the detected reason (e.g. pkgVersion 1.10.0 pre-dates stable embedders). The capability probe is cached for 5 minutes, so an engine upgrade is picked up shortly after.
Enabling It (Admin)
Open Index Settings and pick AI Semantic Search (under the AI Search category in the sidebar). Flip Enable AI semantic search, then configure:
| Field | Default | Notes |
|---|---|---|
| Model | text-embedding-3-small | Or text-embedding-3-large. Switching auto-fills Dimensions. |
| Dimensions | 1536 | 3072 is auto-filled for -large. Editable (clamped to 1–3072). |
| Document template | Index-aware (see below) | Template that renders each document into the text that gets embedded. Pre-filled with the index type's own default. |
| Template max bytes | 3000 | Rendered template text is capped at this size (100–100,000). |
| OpenAI API Key | — | Stored server-side, shown masked (******** + last 4 chars). Leaving the masked value unchanged keeps the saved key. |
| Semantic ratio | 0.5 | Slider from 0 to 1: 0 is pure keyword search, 1 is pure semantic search. |
v1 ships one provider: OpenAI. The Provider dropdown only appears once additional sources are registered via celersearch_embedder_sources.
At a semantic ratio of 0, no hybrid parameters are sent at all — searches behave exactly like plain keyword search (and no query embeddings are requested).
Document Templates
The document template is a liquid snippet the engine renders for every document to produce the text that gets embedded. Each index type pre-fills a default built from the fields its documents actually emit — the field names differ per type:
| Index type | Document fields used |
|---|---|
| Posts | title, excerpt, content |
| Products | post_title, short_description, content |
| Orders | number, status_name, customer, billing, items[] |
For example, the products default:
{% if doc.post_title %}{{ doc.post_title }}
{% endif %}{% if doc.short_description %}{{ doc.short_description }}
{% endif %}{% if doc.content %}{{ doc.content }}{% endif %}
Guard every field
Rendering is strict: referencing a field a document doesn't have fails that document's entire batch — and since a rebuild clears the index first, a bad template leaves the index empty. Always wrap fields in {% if doc.field %}…{% endif %} guards, and only reference fields your index type emits.
Third-party index types can supply their own default via the celersearch_embedder_document_template filter (receives the template and the index).
Rebuilds and Embedding
Embedder settings ride the same settings push as everything else in Index Settings. Two consequences worth knowing:
- Rebuilds re-apply the embedder automatically. A full rebuild deletes and recreates the remote index — the embedder config is re-pushed as part of that, before any documents flow. No manual re-configuration needed.
- Rebuilds embed incrementally. Because the embedder is in place before documents arrive, each rebuild batch is embedded as it's indexed — there's no separate "embed everything" pass at the end.
New and updated documents are embedded automatically through real-time sync. Documents that were already indexed before you enabled the embedder have no vectors yet — run a full Rebuild once to embed them.
Where Hybrid Search Applies
Once enabled, hybrid search is injected centrally — every CelerSearch call path gets it automatically:
- Main site search (WordPress query interception)
- Autocomplete
- WooCommerce shop filters
No per-area configuration. Code that passes its own hybrid parameter wins over the automatic injection (see celersearch_hybrid_search_params below).
Costs
Embedding calls go to OpenAI using your API key:
- One embedding per document at index time (and again whenever a document changes).
- One embedding per search query at search time (skipped when the semantic ratio is 0).
OpenAI's embedding models are billed per token; the document template and its byte cap control how much of each document is sent.
Sizing
On CelerSearch Cloud, semantic and hybrid search is included on the Semantic AI plans (Pro AI, Business AI, Scale AI and Ultra AI). Semantic search stores an AI representation of every document alongside its text, so AI plans hold fewer documents than keyword plans at the same tier.
Counts assume standard AI embeddings (such as text-embedding-3-small); high-precision embeddings (such as text-embedding-3-large) use about twice the capacity, and every extra embedder adds to it. See Plans for pricing and what counts toward capacity.
Developer Hooks
See also Service Hooks for the rest of the Meilisearch settings surface.
celersearch_embedder_sources
Register additional embedder sources (e.g. Meilisearch's rest, ollama, or userProvided sources). Fields render generically in the admin UI, secret fields get masking automatically, and — because sources registered here feed the same settings push — external configs inherit the rebuild persistence described above.
add_filter('celersearch_embedder_sources', function ($sources) {
$sources[] = [
'slug' => 'ollama',
'label' => 'Ollama',
'fields' => [
[
'name' => 'url',
'label' => fn() => __('Ollama URL', 'my-plugin'),
'type' => 'text',
'default' => 'http://localhost:11434/api/embed',
'engine_key' => 'url',
],
[
'name' => 'model',
'label' => fn() => __('Model', 'my-plugin'),
'type' => 'text',
'default' => 'nomic-embed-text',
'engine_key' => 'model',
],
[
'name' => 'document_template',
'label' => fn() => __('Document template', 'my-plugin'),
'type' => 'textarea',
// Context-less fallback; with an index in scope the default is
// the index type's own template. Guard fields with {% if %}.
'default' => "{% if doc.title %}{{ doc.title }}\n{% endif %}{% if doc.content %}{{ doc.content }}{% endif %}",
'engine_key' => 'documentTemplate',
],
[
'name' => 'api_key',
'label' => fn() => __('API Key', 'my-plugin'),
'type' => 'password',
'secret' => true,
'default' => '',
'engine_key' => 'apiKey',
],
],
];
return $sources;
});
Each field's engine_key maps it onto the Meilisearch embedder payload; an optional sanitize callable cleans the posted value.
celersearch_service_meilisearch_embedders
Filter the final embedders payload pushed to Meilisearch — keyed by embedder name (the plugin manages the default embedder).
add_filter('celersearch_service_meilisearch_embedders', function ($embedders, $index, $service) {
// Add a second, engine-side embedder alongside the plugin-managed one
$embedders['custom'] = [
'source' => 'userProvided',
'dimensions' => 768,
];
return $embedders;
}, 10, 3);
When the array ends up empty, the embedders key is omitted from the settings push entirely — non-destructive to embedders managed outside the plugin.
celersearch_hybrid_search_params
Per-query override of the injected hybrid parameters. Return null (or an empty value) to disable hybrid for that query, or tweak the ratio:
add_filter('celersearch_hybrid_search_params', function ($hybrid, $index, $params) {
// Lean more semantic for a specific index
if ($hybrid && $index->get_slug() === 'products') {
$hybrid['semanticRatio'] = 0.8;
}
return $hybrid;
}, 10, 3);
Callers may also set hybrid in the search params themselves — a caller-provided value (including an explicit null) always wins over the automatic injection.
Next Steps
- Cloud plans — Semantic AI plans for semantic and hybrid search
- Dynamic Search Rules — merchandising with pinned results
- Creating indices — rebuilding and the Index Browser
- Service hooks — the full Meilisearch settings surface