WARNING: Version 5.x has passed its EOL date.
This documentation is no longer being maintained and may be removed. If you are running this version, we strongly advise you to upgrade. For the latest information, see the current release documentation.
Multi fields
editMulti fields
editIt is often useful to index the same field in Elasticsearch in different ways, to
serve different purposes, for example, mapping a POCO string
property as a
text
datatype for full text search as well as mapping as a keyword
datatype for
structured search, sorting and aggregations. Another example is mapping a POCO string
property to use different analyzers, to serve different full text search needs.
Let’s look at a few examples. for each, we use the following simple POCO
public class Person { public string Name { get; set; } }
Default mapping for String properties
editWhen using Auto Mapping, the inferred mapping for a string
POCO type is a text
datatype with multi fields including a keyword
sub field
var createIndexResponse = _client.CreateIndex("myindex", c => c .Mappings(ms => ms .Map<Person>(m => m .AutoMap() ) ) );
This results in the following JSON request
{ "mappings": { "person": { "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } }
This is useful because the property can be used for both full text search as well as for structured search, sorting and aggregations
var searchResponse = _client.Search<Person>(s => s .Query(q => q .Match(m => m .Field(f => f.Name) .Query("Russ") ) ) .Sort(ss => ss .Descending(f => f.Name.Suffix("keyword")) ) .Aggregations(a => a .Terms("peoples_names", t => t .Field(f => f.Name.Suffix("keyword")) ) ) );
{ "query": { "match": { "name": { "query": "Russ" } } }, "sort": [ { "name.keyword": { "order": "desc" } } ], "aggs": { "peoples_names": { "terms": { "field": "name.keyword" } } } }
Multi fields do not change the original _source
field in Elasticsearch; they affect only how
a field is indexed.
New multi fields can be added to existing fields using the Put Mapping API.
Creating Multi fields
editMulti fields can be created on a mapping using the .Fields()
method within a field mapping
var createIndexResponse = _client.CreateIndex("myindex", c => c .Mappings(ms => ms .Map<Person>(m => m .Properties(p => p .Text(t => t .Name(n => n.Name) .Fields(ff => ff .Text(tt => tt .Name("stop") .Analyzer("stop") ) .Text(tt => tt .Name("shingles") .Analyzer("name_shingles") ) .Keyword(k => k .Name("keyword") .IgnoreAbove(256) ) ) ) ) ) ) );
Use the stop analyzer on this sub field |
|
Use a custom analyzer named "named_shingles" that is configured in the index |
|
Index as not analyzed |
{ "mappings": { "person": { "properties": { "name": { "type": "text", "fields": { "stop": { "type": "text", "analyzer": "stop" }, "shingles": { "type": "text", "analyzer": "name_shingles" }, "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } }