elasticsearch/elasticsearch — pull request #2463 by mauaht (2012-12-05 00:58:33+00:00)
Title: Added options to DynamicTemplate

Dynamic templates are a great feature because they make it possible to control the dynamic mapping capabilities of ElasticSearch. One of the issues with dynamic templates is that it is necessary to have several templates to handle even very small differences in mapping objectives.
For example, four templates are needed to handle the cases 'analyzed', 'not_analyzed',
'analyzed+stored' and 'not_analyzed+stored'.

This change overcomes this limitation by adding three new features to dynamic templates
1. Options that are merged into the mapping based on keys specified in the field name
2. The ability to capture substrings from the field name and use these to parameterize the mapping and options
3. The ContentPath is made available to the DynamicTemplate for use in parameterization

Consider the following example:

{
"template_1":{
"match": "*__*",
"capture":"(([a-zA-Z0-9]+?)(?:_[a-zA-Z0-9]+)*)__[a-zA-Z0-9]+",
"options" :{
"s":{"type":"string"},
"l":{"type":"long"},
"m":{"index_name":"{1}"},
"n":{"index_name":"{path}.{2}"},
"i":{"index":"not_analyzed"},
"j":{"index":"no"},
"t":{"store":true},
"a":{"include_in_all":false},
"1":{"boost":1.5},
"d":{"dynamic":false}
},
"mapping": {
"index_name":"{path}.{1}"
}
}
}

The match, path_match, unmatch, path_unmatch are unchanged.
Two new optional fields:
"capture" : This specifies a regular expression with capture groups that are used to
capture substrings from the field name that are made available as paramaeters ({1},{2}, etc)
for substitution into option and mapping key/value pairs in the same way that {name} and
{dynamic_type} are currently.

"options" : A list of key/value pairs where keys are single character identifiers
and values are objects containing mapping options that are merged into the "mapping".

If the field name has a double underscore "__" then the DynamicTemplate class treats any characters following it as option identifiers. The following example "person" document and resulting mapping illustrate how this one options enabled dynamic template does what would otherwise require 5 dynamic templates without options.

Notes
1. The {path} parameter strips out the option specifiers. A {raw_path} is also available.
2. Fields 'name_first_sn' and 'name_last_sn1' both map to the index field 'details.name'

index/person/id1
{
"details__d":{
"salutation":"Mr",
"name_first__sn":"",
"name_last__sn1":"",
"marital_status__sit":"married",
"num_children__l":3
}
}

mapping for type person
{
"person" :{
"properties" : {
"details__d" : {
"type":"object",
"dynamic":false, // option 'd'
"properties" {
"salutation" : {
"type":"string"; // Not picked up by match, default mapping
},
"name_first__sn": {
"type":"string", // option 's'
"index_name":"details.name" // option 'n'
},
"name_last__sn1": {
"type":"string", // option 's'
"index_name":"details.name", // option 'n'
"boost":1.5 // option '1'
},
"marital_status__sit": {
"type":"string", // option 's'
"index_name":"details.marital_status", // mapping
"index":"not_analyzed", // option 'i'
"store":true // option 't'
},
"num_children__l":{
"type":"long", // option l
"index_name":"details.num_children", // mapping
}
}
}
}
}
}