4

I have an existing mapping for a field, and I want to change it to a multi-field.

The existing mapping is

{
   "my_index": {
      "mappings": {
         "my_type": {
            "properties": {
               "author": {
                  "type": "string"
               },
               "isbn": {
                  "type": "string",
                  "analyzer": "standard",
                  "fields": {
                     "ngram": {
                        "type": "string",
                        "search_analyzer": "keyword"
                     }
                  }
               },
               "title": {
                  "type": "string",
                  "analyzer": "english",
                  "fields": {
                     "std": {
                        "type": "string",
                        "analyzer": "standard"
                     }
                  }
               }
            }
         }
      }
   }
}

Based on the documentation, I should be able to change "author" to a multi-field by executing the following

PUT /my_index
{
  "mappings": {
        "my_type": {
            "properties": {
                "author": 
                { 
                    "type": "multi-field",
                    "fields": {
                        "ngram": {
                          "type": "string",
                          "indexanalyzer": "ngram_analyzer",
                          "search_analyzer": "keyword"
                        },
                         "name" : {
                         "type": "string"
                        }
                    }
                }              
            }
        }
    }
}

But instead I get the following error:

{
"error": "IndexAlreadyExistsException[[my_index] already exists]",
"status": 400
}

Am I missing something really obvious?

4
  • can you try POST instead of PUT? Commented Dec 17, 2014 at 14:22
  • PUT is good, but as the error states, the index already exists, and you can not change the mapping of an existing index. You have to delete it, then create it with the new mapping. If you have data you want to keep in that index, use scan & scroll API to move data to another index, then delete my_index, create it with the new mapping, and move the data back to my_index Commented Dec 17, 2014 at 14:31
  • Thanks for clarifying juliendangers. But I am confused as to why the Elastic documentation that I linked to says that you can do it when adding multi-field mappings: Any scalar field (ie excluding fields of type object or nested) can be upgraded to a multi-field without reindexing, using the put_mapping API Commented Dec 17, 2014 at 17:37
  • Using POST /my_index returns the same error as PUT. Using POST /my_index/_mapping also does not work, as it returns the error: "ActionRequestValidationException[Validation Failed: 1: mapping type is missing;]" Commented Dec 17, 2014 at 17:42

3 Answers 3

1

Instead of PUT to /my_index do:

POST /my_index/_mapping
Sign up to request clarification or add additional context in comments.

1 Comment

I got this error instead: Validation Failed: 1: mapping type is missing;
1

You won't be able to change the field type in an already existing index. If you can't recreate your index you can make use of the copy to field to achieve a similar capability.

   PUT /my_index
        {
          "mappings": {
           "my_type": {
        "properties": {
                   "author": 
                   { 
                      "type": "string",
                      "copy_to": ["author-name","author-ngram"]
                   }

                    "author-ngram": {
                      "type": "string",
                      "indexanalyzer": "ngram_analyzer",
                      "search_analyzer": "keyword"
                    },
                     "author-name" : {
                     "type": "string"
                    }

            }              
          }
       }
     }
  }

Comments

1

While I have not tried it in your particular example, it is indeed possible to update field mappings by first closing the index and then applying the mappings.

Example:

POST /my_index/_close
POST /my_index/_mapping
{
     "my_field:{"new_mapping"}
}
POST /my_index/_open

I have tested it, by adding a "copy_to" mapping property to mapped field.

Based on https://gist.github.com/nicolashery/6317643.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.