fast prefix matches directly on field values without a full search
For a simple autocomplete on brand or category names, a full-fledged completion suggester with its own suggest index and dedicated mapping is often overkill. The terms enum API offers a considerably lighter alternative: it reads the unique values already present in a field's term index directly and returns prefix matches, without running a complete search request with scoring, relevance calculation, or document retrieval. That makes it well suited for fast suggestion lists on low-cardinality keyword fields such as brand or category names. How the terms enum API works technically, how it differs from the completion suggester, and how a practical brand autocomplete can be built on top of it is what this article covers.
Table of Contents
- 1. The baseline problem: lightweight autocomplete without overhead
- 2. Basics: how the terms enum API delivers prefix matches
- 3. Case sensitivity, timeout, and fault tolerance
- 4. Distinction from the completion suggester
- 5. Practical example: brand and category name autocomplete
- 6. Performance characteristics compared to classic search
- 7. Limitations: what the terms enum API is not suited for
- 8. Combining with index_filter for context-dependent suggestions
- 9. Deciding when to use it: a short checklist
- 10. Summary
- 11. FAQ
1. The baseline problem: lightweight autocomplete without overhead
Autocomplete suggestions for brand or category names rarely need elaborate scoring, fuzzy matching, or context-dependent weighting the way a full completion suggester provides. Usually a fast, alphabetically sorted list of every value starting with what the user has typed so far is enough, for instance every brand starting with bos. Setting up a completion suggester for that means extra mapping effort with a dedicated completion field that needs to be populated separately and kept in sync on every indexing operation.
The terms enum API takes a different approach: instead of searching documents, it iterates directly over the term index already present on a regular keyword field and returns the unique values starting with a given prefix. Since these values are indexed anyway for regular search and aggregations, this creates no additional storage or maintenance overhead at all.
2. Basics: how the terms enum API delivers prefix matches
A call to the _terms_enum API requires at minimum the target field and a prefix string, and returns a list of unique term values starting with that prefix, limited to the ten most common by default through the size parameter. The response also includes a complete field indicating whether every matching term is genuinely included in the response, or whether a time limit or shard boundary cut the search short for performance reasons.
Unlike a normal search request, the terms enum API does not evaluate relevance or scoring at all, the returned order instead follows the internal ordering of the term index, usually alphabetical within a segment. For an autocomplete field this is generally sufficient, since a simple alphabetical or frequency-sorted list is expected anyway, with no need for content-based relevance evaluation.
POST /products/_terms_enum
{
"field": "brand",
"string": "bos",
"size": 10
}
// response:
{
"terms": ["bosch", "boston_gear"],
"complete": true
}
3. Case sensitivity, timeout, and fault tolerance
The case_insensitive parameter controls whether the prefix search takes letter casing into account, which is practically always desirable for user-typed input in a search field, since users rarely stick consistently to correct casing. The API also supports an optional regular expression beyond a plain string for more complex pattern matching, though this is rarely needed for simple prefix autocomplete.
The timeout parameter limits the maximum execution time per shard and prevents a request from running uncontrolled long against a very large, fragmented term index. If the time limit expires before every shard has fully responded, the API returns the results collected so far and marks complete as false, which the application can use as a hint that the suggestion list may be incomplete.
4. Distinction from the completion suggester
The completion suggester is designed for autocomplete that requires genuine relevance ranking, weighting of individual suggestions, fuzzy matching for typos, and context-dependent filtering, for instance prioritizing suggestions by region or user profile. It needs its own completion field in the mapping, which must be explicitly populated at index time with the desired input texts and optional weights, meaning additional maintenance effort whenever source data changes.
The terms enum API, by contrast, needs no separate field and no additional data maintenance, working directly on an already existing keyword field, which makes it especially suitable for fields with manageable cardinality where fixed, controlled values already exist anyway, such as brands, categories, or manufacturers. For free-text autocomplete with a very large number of possible distinct values and a genuine need for relevance ranking, the completion suggester remains the better choice.
5. Practical example: brand and category name autocomplete
In the practical scenario, a user types the first letters of a brand name into a search interface's filter field, and the application calls the terms enum API with the current prefix against the brand field on every keystroke. Since the field is already indexed as keyword for filtering and facets, no additional indexing cost arises, the suggestion list uses exactly the same values also used for the actual product filtering.
The same approach works identically for category names, with the added benefit that the terms enum request can be combined with an index_filter where needed, to only suggest categories that actually contain currently available products, instead of showing stale or empty categories.
POST /products/_terms_enum
{
"field": "category",
"string": "pow",
"case_insensitive": true,
"index_filter": {
"range": { "stock": { "gt": 0 } }
}
}
6. Performance characteristics compared to classic search
Because the terms enum API does not load documents, does not compute relevance, and does not perform highlighting, it is generally considerably faster than an equivalent match_phrase_prefix search or an aggregation with prefix filtering on the same field. Access happens nearly directly against the term index's data structure, which keeps response times well within the low millisecond range even under very frequent autocomplete requests per keystroke.
For fields with very high cardinality, for instance free-text input with millions of distinct values, the cost of scanning the term index still rises noticeably, especially when many segments each with their own term index need to be traversed. For fields with a manageable, controlled value set like brands or categories, however, performance stays practically constant regardless of the total number of documents in the index.
7. Limitations: what the terms enum API is not suited for
The terms enum API is not suited for fuzzy matching against typos, since it exclusively checks exact prefixes against the term index and supports no edit distance or similar tolerance mechanism. It equally lacks any form of weighting or prioritization of individual suggestions by popularity or business logic, every matching term appears with equal standing in the response, sorted only by the internal term index order.
For multilingual autocomplete requirements with different language variants of the same term, or for free-text full-text search with tokenization, the terms enum API is also unsuitable, since it operates directly on unanalyzed keyword values and applies no analyzer logic at all. In such cases either the completion suggester or a classic match_phrase_prefix query remains the more fitting solution.
8. Combining with index_filter for context-dependent suggestions
The optional index_filter parameter allows restricting the terms enum request to a subset of documents before the term index gets scanned, for instance only documents belonging to a specific shop or a specific language. This makes context-dependent suggestion lists possible without maintaining separate indices per context, considerably reducing maintenance effort compared to several dedicated completion suggester fields.
It matters that a set index_filter adds evaluation overhead, since Elasticsearch has to check, for every candidate term, whether at least one matching document satisfies the filter. For very restrictive filters combined with very large term indices, it is therefore worth checking actual response time under realistic load before rolling this approach out for high-traffic autocomplete fields.
9. Deciding when to use it: a short checklist
The terms enum API fits well when the target field is already indexed as keyword, the value set stays manageable, and no genuine relevance ranking or fuzzy matching is required, typically for brands, categories, manufacturer names, or similar controlled attributes. As soon as typo tolerance, popularity weighting, or context-dependent scoring are needed, there is no way around a full completion suggester.
In practice, combining both approaches within the same system often pays off: terms enum for fast, lightweight filter suggestions on structured attribute fields, and completion suggester wherever genuine full-text autocomplete quality with relevance scoring is required, for instance in global free-text product search.
| Criterion | Terms Enum API | Completion Suggester | Practical relevance |
|---|---|---|---|
| Extra mapping field | Not needed | Dedicated completion field required | Terms enum saves maintenance effort |
| Relevance ranking | No scoring | Genuine weighting and scoring system | Suggester for popularity-based ordering |
| Fuzzy matching for typos | Not supported | Supported | Suggester for typo-tolerant input |
| Suitable field cardinality | Low to medium | Any, optimized for scale | Terms enum ideal for brands/categories |
| Performance under frequent requests | Very fast, minimal overhead | Fast, but with index overhead | Terms enum practical on every keystroke |
Mironsoft
Search index setup, relevance tuning, and Magento search
Magento search that shows the wrong products first?
We set up Elasticsearch or OpenSearch for Magento cleanly, tune relevance and facets to the actual catalog, and optimize indexing processes for large catalogs.
Relevance Tuning
Match search results and facets to actual customer needs.
Search Migration
Guide a clean migration from Solr or MySQL search to Elasticsearch/OpenSearch.
Index Performance
Make indexing processes for large catalogs reliable and performant.
10. Summary
Terms Enum API: The Essentials at a Glance
Core principle
The terms enum API reads prefix matches directly from an existing keyword field's term index, without running a full search request with scoring.
Distinction
Unlike the completion suggester it needs no dedicated mapping field, but it also delivers no relevance ranking or fuzzy matching for typos.
Best use case
Brand, category, or manufacturer name autocomplete on fields with a manageable, controlled value set benefits the most.
Combination
Terms enum and completion suggester can run side by side in the same system for different autocomplete requirements.