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
string
datatype for full text search as well as mapping as a not_analyzed
string
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.
public class Person { public string Name { get; set; } }
Creating Multi fields
editLet’s look at an example, using the following simple POCO
Multi fields can be created on a mapping using the .Fields()
method within a field mapping
var descriptor = new CreateIndexDescriptor("myindex") .Mappings(ms => ms .Map<Person>(m => m .Properties(p => p .String(t => t .Name(n => n.Name) .Fields(ff => ff .String(tt => tt .Name("stop") .Analyzer("stop") ) .String(tt => tt .Name("shingles") .Analyzer("name_shingles") ) .String(k => k .Name("keyword") .IgnoreAbove(256) .NotAnalyzed() ) ) ) ) ) );
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": "string", "fields": { "stop": { "type": "string", "analyzer": "stop" }, "shingles": { "type": "string", "analyzer": "name_shingles" }, "keyword": { "type": "string", "ignore_above": 256, "index": "not_analyzed" } } } } } } }
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.
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 Cam") ) && q .Match(m => m .Field(f => f.Name.Suffix("shingles")) .Query("Russ Cam") .Boost(1.2) ) ) .Sort(ss => ss .Descending(f => f.Name.Suffix("keyword")) ) .Aggregations(a => a .Terms("peoples_names", t => t .Field(f => f.Name.Suffix("keyword")) ) ) );
{ "query": { "bool": { "must": [ { "match": { "name": { "query": "Russ Cam" } } }, { "match": { "name.shingles": { "query": "Russ Cam", "boost": 1.2 } } } ] } }, "sort": [ { "name.keyword": { "order": "desc" } } ], "aggs": { "peoples_names": { "terms": { "field": "name.keyword" } } } }