indexing one value multiple ways for flexible queries
Full text search, exact filtering, sorting and aggregation place conflicting demands on the very same field value. Multi-fields resolve that conflict by indexing one value in several parallel representations at once, so each query type uses the representation it needs without duplicating any data.
Table of Contents
- 1. The core problem: one value, several conflicting requirements
- 2. What multi-fields are and how the fields parameter works
- 3. The classic keyword sub field for sorting and filters
- 4. Combining multiple analyzers on the same field
- 5. Autocomplete sub fields with their own tokenizer
- 6. Addressing multi-fields in queries: dot notation
- 7. Storage and indexing costs of multi-fields
- 8. Creating multi-fields automatically via dynamic templates
- 9. A complete practical example: a product name with three fields
- 10. Summary
- 11. FAQ
1. The core problem: one value, several conflicting requirements
A single text field like a product name often needs to satisfy several requirements at once in practice, requirements that no single field type can cover. For full text search, the value must be analyzed and split into individual tokens so a partial search works. For sorting by product name and for exact filtering by that exact name, the unmodified, exact string is needed instead. A text field alone cannot do the latter, a keyword field alone cannot do the former.
Multi-fields solve exactly this problem by allowing a single source value to be stored in several parallel representations within the same index. Instead of making compromises or writing data redundantly into several separate fields, you define a main field and additional sub fields that get automatically populated with the same value during indexing, but processed differently. This article shows how multi-fields are configured, which strategies have proven themselves, and where the limits lie.
2. What multi-fields are and how the fields parameter works
Multi-fields are defined via the fields parameter in a field's mapping. Every sub field inside fields has its own name and its own, fully independent type and analyzer configuration, but is automatically populated with the same input value as the main field. There is no separate write logic needed in the application: a single JSON value in the indexed document is enough, Elasticsearch internally handles the parallel indexing across all configured representations.
Technically, every sub field creates its own Lucene field in the underlying segment, fully separate from the main field. From the application's perspective, however, the document remains a single JSON object with a single key. This separation between the logical structure in the source document and the physical structure in the index is the central advantage of multi-fields over the alternative of maintaining several separate top level fields with redundant content.
PUT /products
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": { "type": "keyword", "ignore_above": 256 }
}
}
}
}
}
// A single value populates both representations automatically
POST /products/_doc
{ "name": "Wireless Headphones Pro" }
// name -> analyzed tokens: wireless, headphones, pro
// name.keyword -> exact string: "Wireless Headphones Pro"
3. The classic keyword sub field for sorting and filters
By far the most common application of multi-fields is the combination of a text main field and a keyword sub field, usually called fieldname.keyword. This combination is so widespread that Elasticsearch automatically creates it for every detected string field when dynamic mapping is enabled, which shows how central this pattern is for practical operation. The main field name stays responsible for full text search, while name.keyword is used for sorting, exact filtering and aggregation.
The ignore_above parameter on the keyword sub field matters here: it prevents excessively long strings, for example accidentally pasted full text instead of a short name, from being indexed and unnecessarily bloating the index. Values that exceed the configured character length are simply not indexed in the keyword sub field, but remain searchable in the main field. This is a simple but effective safeguard against unusually long input data.
4. Combining multiple analyzers on the same field
Multi-fields are not limited to the text plus keyword combination. A common advanced use case is indexing the same text value with two different analyzers, for example once with a language specific analyzer for stemming based search and once with a simpler analyzer without stemming for more exact phrase search. A search can then be run specifically against the appropriate sub field, depending on whether a broad or a precise result set is desired.
Another pattern is combining a standard analyzer with an asciifolding analyzer that normalizes accents and special characters. This way a search for "cafe" also finds documents containing "café", while the main field still keeps the more precise, accent sensitive variant for cases where the distinction matters. These combinations allow querying multiple search quality tiers in the same query with different weighting, for example through a multi_match query across several fields with boost factors.
PUT /articles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "standard",
"fields": {
"stemmed": { "type": "text", "analyzer": "english" },
"folded": { "type": "text", "analyzer": "simple" }
}
}
}
}
}
// Query multiple representations with different weights
GET /articles/_search
{
"query": {
"multi_match": {
"query": "cafe corner",
"fields": ["title^3", "title.stemmed^2", "title.folded"]
}
}
}
5. Autocomplete sub fields with their own tokenizer
Another well established pattern is a sub field with an edge_ngram tokenizer for autocomplete functionality. While the main field indexes whole words for normal search, the sub field name.autocomplete splits the same value into overlapping prefixes, so matching suggestions appear after just the first three or four typed characters. This technique saves a separate suggest infrastructure for many simple autocomplete use cases.
With this pattern it is crucial that the edge_ngram tokenizer is only applied at index time, not at search time, otherwise the search term itself would also be split into prefixes and compared with itself in unexpected ways. The search_analyzer parameter on the sub field is therefore typically set to a simple standard analyzer, while only the index analyzer performs the edge_ngram splitting.
6. Addressing multi-fields in queries: dot notation
In queries, multi-fields are addressed via dot notation, that is fieldname.subfieldname, as in name.keyword in a term query or a sort clause. This notation is purely syntactic for the query DSL and has nothing to do with an actually nested JSON structure in the source document, which stays flat. This separation occasionally confuses developers new to Elasticsearch, because the dot notation looks like nested objects, even though it refers to a single flat field with several internal representations.
A common mistake is trying to set a sub field directly in the document while indexing, for example {"name.keyword": "value"}. This actually creates a new, separate top level field with a dot in its name, not the intended sub field. Multi-fields are populated exclusively and automatically from the main field's value and cannot be addressed directly during indexing. Knowing this rule avoids one of the most common points of confusion when working with multi-field mapping.
7. Storage and indexing costs of multi-fields
Every additional sub field incurs its own storage and CPU cost, because it is indexed as a fully separate Lucene field. For a product name with two or three sub fields, this overhead is usually negligible, but it can become noticeable with very large text fields, for example full article bodies duplicated across multiple analyzer variants. An index with five sub fields on a long description text roughly quintuples the storage requirement and indexing time for exactly that field.
The practical consequence: multi-fields should be applied deliberately to fields that actually need several query types, not blanket applied to every text field in the mapping. A pure description field that is only searched, never sorted or aggregated, does not need a keyword sub field. This deliberate trade off between query flexibility and resource consumption is part of any well thought out mapping strategy.
8. Creating multi-fields automatically via dynamic templates
For indices with many similarly structured fields, for example custom attributes in a product catalog, combining multi-fields with dynamic templates pays off. Instead of manually adding a keyword sub field to the mapping for every new string attribute, a dynamic template can automatically define that every newly detected string field gets equipped with a keyword.raw sub field. New attributes then get consistent multi-field structures without manual intervention.
This automation significantly reduces configuration overhead, but should be combined with the same storage cost considerations as a manually maintained mapping. A dynamic template that automatically adds several expensive sub fields to every string, in combination with uncontrolled dynamic mapping, can multiply the already risky field growth. Combining both techniques therefore requires the same care as either one on its own.
PUT /catalog
{
"mappings": {
"dynamic_templates": [
{
"strings_with_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"raw": { "type": "keyword", "ignore_above": 256 }
}
}
}
}
]
}
}
9. A complete practical example: a product name with three fields
A realistic example ties the presented techniques together. A product name in an online shop needs to satisfy three requirements at once: full text search via the main field with a standard analyzer, exact sorting and aggregation via a keyword sub field, and autocomplete suggestions while typing via a third sub field with an edge_ngram tokenizer. All three representations are produced from the same single JSON value during indexing, without the application ever writing the value more than once.
In the search interface, these three fields get combined deliberately: the autocomplete suggestion while typing queries name.autocomplete, the actual search after confirmation uses the main field name for broad relevance, and the result list, if needed, sorts by name.keyword for a stable, alphabetical order. This clean separation by purpose is the core of every good multi-field strategy: not creating as many sub fields as possible, but exactly the ones that serve a concrete query purpose.
For Magento operators using the Elasticsearch catalog index, it is relevant that the default indexing already automatically creates multi-field structures for many attributes, for example the product name. Anyone needing custom attributes with both full text search and sortability should check whether the generated mapping structure already includes a suitable sub field before building a custom solution via a plugin or indexer hook.
| Sub field purpose | Field type / analyzer | Typical name | Use case |
|---|---|---|---|
| Exact comparison | keyword |
name.keyword |
Sorting, filters, aggregation |
| Precise phrase search | text, simple analyzer |
title.folded |
Accent insensitive exact search |
| Stemming search | text, language analyzer |
title.stemmed |
Broad recall across word forms |
| Autocomplete | text, edge_ngram |
name.autocomplete |
Suggestions while typing |
This overview shows four proven patterns that can be combined freely on a single field. The key is to set up every sub field deliberately for a concrete query purpose, instead of preemptively creating every possible variant and thereby incurring unnecessary cost.
10. Summary
Multi-fields resolve the conflict between full text search, exact filtering, sorting and aggregation on the same logical value by indexing a single source in several parallel representations. The fields parameter in the mapping makes this possible without changing any application logic: a single JSON value is enough, Elasticsearch handles the internal duplication across the different representations.
The classic keyword sub field covers the most common case, while additional analyzer variants and edge_ngram sub fields cover more advanced requirements such as multi tier relevance or autocomplete. Because every sub field incurs storage and indexing cost, multi-fields should be applied deliberately for actual query requirements, not blanket applied to every field in the mapping.
Multi-field mapping, the essentials at a glance
fields parameter
Creates several parallel representations from one value in the same index, without redundant application logic.
keyword sub field
Default pattern for sorting, filtering and aggregation on an otherwise analyzed text field.
Dot notation
fieldname.subfieldname in queries, not a nested object in the source document.
Watch the cost
Every sub field costs storage and indexing time, apply deliberately rather than blanket.