Enable keyword search to match chunks that contain your query terms exactly. For an overview of search modes, refer to Search modes.
Set index_method.keyword to true when creating or updating an instance. You can use keyword search on its own or alongside vector search for hybrid search.
| Field | Type | Default | Description |
|---|---|---|---|
vector |
boolean | true |
Enable vector (semantic) search. |
keyword |
boolean | false |
Enable keyword (BM25) search. |
At least one of vector or keyword must be true. Changing index_method triggers a full reindex of your content.
const instance = await env.AI_SEARCH.create({
id: "my-instance",
index_method: {
vector: false,
keyword: true,
},
});The keyword_tokenizer field (inside indexing_options) controls how text is split into tokens. Changing this triggers a full reindex.
| Value | Default | Description |
|---|---|---|
porter |
Yes | Applies Porter stemming. "running" matches "run." Best for natural language. |
trigram |
No | Overlapping 3-character windows. "config" matches "configuration." Best for code. |
The keyword_match_mode field (inside retrieval_options) controls how multiple query terms are combined.
| Value | Default | Description |
|---|---|---|
and |
Yes | All query terms must appear. Higher precision, fewer results. |
or |
No | Any query term can match. Higher recall, more results. |
You can override keyword_match_mode per request:
const instance = env.AI_SEARCH.get("my-instance");
const results = await instance.search({
messages: [{ role: "user", content: "What is Cloudflare?" }],
ai_search_options: {
retrieval: {
keyword_match_mode: "or",
},
},
});Instances with keyword search enabled support up to 500,000 files per instance on the Workers Paid tier, compared to 1,000,000 for vector-only instances. Refer to Limits and pricing for the full list of limits.