Change Default Mapping of String to "Not Analyzed" in Elasticsearch

Better Stack Team
Updated on October 26, 2024

To change the default mapping of string fields to "not analyzed" in Elasticsearch, especially in Elasticsearch 5.x and earlier (when string was a field type), you would typically modify the mappings of your indices. In Elasticsearch 6.x and later, string fields were replaced by text (for analyzed content) and keyword (for not-analyzed content). Thus, the approach would differ slightly depending on the Elasticsearch version you're using.

Here’s how you can adjust the default mapping for string (or keyword) fields to be not analyzed:

1. Elasticsearch 6.x and Later

In Elasticsearch 6.x and later, use the keyword type to store strings as not analyzed. You can define a template or directly set the mapping when creating an index.

Using Index Templates

You can create a template that applies to new indices and sets the string fields as keyword (not analyzed) by default.

  1. Create an Index Template:

    This template will apply to any new indices that match the pattern (e.g., logs-*).

     
    PUT _template/not_analyzed_strings
    {
      "index_patterns": ["logs-*"],
      "mappings": {
        "properties": {
          "your_field": {
            "type": "keyword"
          }
        }
      }
    }
    
    
 
- **`index_patterns`**: Matches the indices where this template will apply (e.g., indices starting with `logs-`).
- **`type: keyword`**: Ensures the string fields are stored as `keyword`, meaning they will not be analyzed.
  1. Create an Index with This Template:

    After setting up the template, any new index matching the pattern will use this mapping.

     
    PUT logs-2024-09
    

    Elasticsearch will automatically apply the keyword type to the your_field field, making it "not analyzed."

Direct Mapping When Creating an Index

You can also define the mapping explicitly when creating an index:

 
PUT /my_index
{
  "mappings": {
    "properties": {
      "my_string_field": {
        "type": "keyword"
      }
    }
  }
}

This will make the my_string_field field "not analyzed."

2. Elasticsearch 5.x and Earlier

In Elasticsearch 5.x, string fields could be set as either analyzed or not analyzed. To make a string field "not analyzed," you needed to specify the index: not_analyzed option in the mapping.

  1. Create an Index Template:

     
    PUT _template/not_analyzed_strings
    {
      "template": "logs-*",
      "mappings": {
        "_default_": {
          "properties": {
            "your_field": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
    
 
- **`index: not_analyzed`**: Specifies that the `string` field will be stored as-is and not analyzed.
- **`template`**: Matches the indices where the template should be applied.
  1. Create the Index:

    When you create an index, Elasticsearch will automatically apply the template and set the your_field as "not analyzed."

     
    PUT logs-2024-09
    

3. Dynamic Template to Apply "Not Analyzed" to All String Fields

You can also create a dynamic template to apply the "not analyzed" setting to all string fields by default.

For Elasticsearch 6.x and Later (Using keyword):

 
PUT _template/default_template
{
  "index_patterns": ["*"],
  "mappings": {
    "dynamic_templates": [
      {
        "strings_as_keywords": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}
  • match_mapping_type: string: This ensures that all string fields are matched.
  • type: keyword: Makes all matched fields "not analyzed."

For Elasticsearch 5.x and Earlier (Using not_analyzed):

 
PUT _template/default_template
{
  "template": "*",
  "mappings": {
    "_default_": {
      "dynamic_templates": [
        {
          "strings_as_not_analyzed": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

This dynamic template ensures that every string field in all indices will be set to "not analyzed."

Summary

  • For Elasticsearch 6.x and Later: Use the keyword type to store string fields as "not analyzed."
  • For Elasticsearch 5.x and Earlier: Use the index: not_analyzed option for string fields.
  • Dynamic Templates: You can apply a dynamic template to automatically make all string fields "not analyzed" by default.

These methods ensure that string fields are not analyzed by Elasticsearch, allowing you to store and search for exact values rather than full-text analysis.

Got an article suggestion? Let us know
Explore more
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Make your mark

Join the writer's program

Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.

Write for us
Writer of the month
Marin Bezhanov
Marin is a software engineer and architect with a broad range of experience working...
Build on top of Better Stack

Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.

community@betterstack.com

or submit a pull request and help us build better products for everyone.

See the full list of amazing projects on github