Changing the field mapping in Elasticsearch without downtime

Want to change the field mapping in Elasticsearch with zero downtime? You've come to the right place. I'll teach you in three easy steps.
💡
In fact, you cannot change the field mapping in an existing index 🥵 But you can get around this restriction 😵💫
We'll use a combined approach: we'll recreate the existing index with the appropriate fields, and then link it to an alias.
We'll do it in four easy steps, let me show you!
Create an index with the desired field mapping (in most cases you will have to copy and paste your old settings and mappings, but change the mapping of the desired field to the appropriate one)
PUT /index_with_new_mappings
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
"my_field": { "type": "text" }
}
}
}2. Link the newly created index to an alias (existing or new, doesn't matter).
POST _aliases
{
"actions": [
{
"add": {
"index": "index_with_new_mappings",
"alias": "alias_to_a_new_index"
}
}
]
}🧐
Yes, after that you must use this alias name in your code instead of the name of the old index
3. Fill the new index with values from the old index
POST _reindex?wait_for_completion=false
{
"source": {
"index": "you_old_index_name"
},
"dest": {
"index": "index_with_new_mappings"
}
}This command will throw the ID of the background reindexing job. You can copy it and check the progress of the operation:
GET _tasks/NMqebTkTRR2L7eYoj7Lvqg:18516646... ... ...
Well... let's assume that our reindexing task is complete
4. The last step: change the name of the index in your code or application to your alias name. Remember. We created it in step 2 and named it "alias_to_a_new_index".
$params = [
'index' => 'alias_to_a_new_index',
'id' => 'my_id'
];
$response = $client->get($params);
print_r($response);5. Failover option. If something went wrong with your new index, you can decouple your new index from the alias and bind the old index to the alias.
POST _aliases
{
"actions": [
{
"remove": {
"index": "index_with_new_mappings",
"alias": "alias_to_a_new_index"
}
},
{
"add": {
"index": "you_old_index_name",
"alias": "alias_to_a_new_index"
}
}
]
}😅
Or you can revert your challenges in code from step 4
That's it! You are awesome
Why don't we want to "expand" the field or create a new one?
Because of the cost of this solution. Expanding a field or creating a new field will drastically reduce indexing performance and require much more time and memory.

