Akasha
Akasha

Reputation: 2212

Set fields to not_analysed in all (future) types under an index in elasticsearch 1.7

I have an index with quite a few types, and new types' creation is not controlled by me. I know that the data structure is pretty solid, but I don't know the type's name in advance.

I would like to set some fields as not_analysed, while some should be analysed. Is there a way to achieve this?

Upvotes: 1

Views: 127

Answers (2)

BrookeB
BrookeB

Reputation: 1769

I would also add to Val's excellent answer that you are probably wanting to add these dynamic templates to the _default_ mapping for your index, since you mentioned you do not know the types in advance. For example:

PUT /my_index/_mapping/_default_
{
  "dynamic_templates": [
    {
      "analyzed": {
        "match_mapping_type": "string",
        "match": "*_text",
        "mapping": {
          "type": "string"
        }
      }
    },
    {
      "not_analyzed": {
        "match_mapping_type": "string",
        "match": "*_key",
        "mapping": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  ]
}

With that in place, you can add any arbitrary type to the index and any fields in the documents added to the new type that end with "_text" will be analyzed. Any fields ending with "_key" will not be analyzed. You can read more about the default mapping in the docs.

Upvotes: 2

Val
Val

Reputation: 217564

Dynamic mappings are the way to go. Since you're mentioning analyzed vs not_analyzed I reckon you're talking about string fields.

The idea is to update your index and mapping in order to include a dynamic template for your string fields:

PUT my_index
{
  "mappings": {
    "my_type": {
      "dynamic_templates": [     <--- include this section in your existing mapping
        {
          "analyzed": {
            "match_mapping_type": "string",
            "match":   "field1",
            "mapping": {
              "type": "string"
            }
          }
        },
        {
          "not_analyzed": {
            "match_mapping_type": "string",
            "match":   "field2",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

Another way would be to make each new string field both analyzed and not_analyzed so you don't have to enumerate all your fields, simply using:

PUT my_index
{
  "mappings": {
    "my_type": {
      "dynamic_templates": [     <--- include this section in your existing mapping
       {
         "strings": {
           "match_mapping_type": "string",   <-- match all string fields
           "mapping": {
             "type": "string",
             "fields": {
               "raw": {
                 "type":  "string",
                 "index": "not_analyzed",
                 "ignore_above": 256
               }
             }
           }
         }
       }
      ]
    }
  }
}

Upvotes: 1

Related Questions