Update mapping of not_analyzed field

I would like to have some clarity on why it is not possible to update a not_analyzed field to a multi field. The documentation is not exactly clear on that (https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html#updating-field-mappings). It states that "new multi-fields can be added to existing fields" but it does not seems to work for not_analyzed fields. Curious on why not?

Examples below are not tested but should reveal the thing i am trying.

PUT my_index
{
"mappings": {
"test": {
"properties": {
"field1": {
"type": "string"
},
"field2": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}

This works fine for field1:

PUT my_index/_mapping/test

{
"mappings": {
"test": {
"properties": {
"field1": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
},
"search": {
"type": "string"
}
}
}
}
}
}
}

This fails for field2:

PUT my_index/_mapping/test

{
"mappings": {
"test": {
"properties": {
"field2": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
},
"search": {
"type": "string"
}
}
}
}
}
}
}

ElasticSearchClient::ElasticSearchError: [400] {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Mapper for [field2] conflicts with existing mapping in other types:\n[mapper [field2] has different [index] values, mapper [field2] has different [omit_norms] values, cannot change from disable to enabled, mapper [field2] has different [analyzer]]"}],"type":"illegal_argument_exception","reason":"Mapper for [field2] conflicts with existing mapping in other types:\n[mapper [field2] has different [index] values, mapper [field2] has different [omit_norms] values, cannot change from disable to enabled, mapper [field2] has different [analyzer]]"},"status":400}

Hi @butsjoh,

the error message says:

mapper [field2] has different [omit_norms] values, cannot change from disable to enabled

You (implicitly) try to enable norms after the fact which is not possible, see the user docs on norms for more information.

You can also see all index settings with the get field mapping API:

GET /my_index/_mapping/test/field/field2?include_defaults=true

Basically, you need to keep the index options (which means, keeping field2 and not_analyzed), then everything works fine:

PUT my_index/_mapping/test
{
   "properties": {
      "field2": {
         "type": "string",
         "index": "not_analyzed",
         "fields": {
            "raw": {
               "type": "string",
               "index": "not_analyzed"
            },
            "search": {
               "type": "string"
            }
         }
      }
   }
}

If you don't want to do that, you need to create a new index and reindex the data from the old index.

Daniel

3 Likes

Ok but it still means i can create multifields for field2 that are analyzed not?

Hi @butsjoh,

yes, the subfields of field2 can have different index options.

Daniel

1 Like