22
votes

Is it possible to enable indexing of elastic search fields selectively for a type?

Through the mapping settings for a specific index, one can set the property

{ "index" : "not_analyzed" }

For a specific field. Since my document has too many fields and is likely to change structure in the future, I would need a mapping where fields are not analyzed by default unless specified differently.

Is this possible?

3

3 Answers

32
votes

Yes - have a look at dynamic templates

Try the following:

PUT /my_index
{
  "mappings": {
    "my_type": {
        "dynamic_templates": [
            { "notanalyzed": {
                  "match":              "*", 
                  "match_mapping_type": "string",
                  "mapping": {
                      "type":        "string",
                      "index":       "not_analyzed"
                  }
               }
            }
          ]
       }
   }
}

The dynamic template is for new fields that aren't covered by your mapping - from the docs:

With dynamic_templates, you can take complete control over the mapping that is generated for newly detected fields.

You can also vary the mapping according to the field name, e.g. use "match": "*_data", to have a different set of mappings for field names ending in "_data".

4
votes

From elasticsearch 5.x string type is disabled. Instead elasticsearch has introduced two types text and keyword. Read this blog for the reasons for migrating data https://www.elastic.co/blog/strings-are-dead-long-live-strings

So instead of adding a template to disable analyzer, you could simply use field.keyword for exact search. e.g. If field name is fullName, and you have entries

  1. fullName:"John Doe"
  2. fullName:"John"

then, fullName:"John" will return two results, while fullName.keyword:"John" will return single record.

Just in case, you still want to disable text field, you can use the below dynamic template,

PUT _template/disable_all_analyzer
   {
     "template": "*",
     "mappings": {
       "_default_": {
           "dynamic_templates": [
               { "notanalyzed": {
                     "match":              "*", 
                     "match_mapping_type": "string",
                     "mapping": {
                         "type":        "keyword"
                     }
                  }
               }
             ]
          }
      }
   }

Cheers!!!

0
votes

Ashay code works properly, but as it does not include an index directive the documents will be stored but not indexed, so you will not able to searches or aggregations.

I suggest include it next way:

PUT _template/disable_all_analyzer
   {
     "template": "*",
     "mappings": {
       "_default_": {
           "dynamic_templates": [
               { "notanalyzed": {
                     "match":              "*", 
                     "match_mapping_type": "string",
                     "mapping": {
                         "type":        "keyword",
                         "index":    "not_analyzed"
                     }
                  }
               }
             ]
          }
      }
   }