Keyword search
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.