Updating a mapping in ElasticSearch
Assumption: we have an index things
with a mapping m1
and the result we want is an index with the same name and the same data but a different mapping m2
. For instance, there might be a string
field in m1
that we want to turn into an indexed date
field.
- Create a backup of the current index just in case
PUT /things-bak
POST /_reindex { "source": { "index": "things" }, "dest": { "index": "things-bak" } }
- Update the mapping in the index template with the new field
GET /_template/things-template
- peel the outer layer by piping through
jq '.things'
- modify the mapping
- update the template with the modified mapping
PUT /_template/things-template <template_json>
- at that point, we have only updated the template,
things
still uses the old mapping which we can check withGET /things/_mapping
- Create a new index with the right name, so that it matches the index pattern from the template. Assuming we have a pattern like
"template": "things*"
,things-v2
would work.PUT /things-v2
- at that point, we have a new index with the new mapping, but it’s empty.
- verify that the new index has the new mapping with
GET /things-v2/_mapping
- Reindex the data from the old to the new index
POST /_reindex { "source": { "index": "things" }, "dest": { "index": "things-v2" } }
- Check that the new index has the data with
GET /index-v2/_search?pretty
- At this point, there are 2 options:
DELETE /things
,PUT /things
(it has the new mapping now), reindexthings-v2
intothings
andDELETE /things-v2
(phew)- or simply
DELETE /things
and create an alias to the new index:POST /_aliases { "actions" : [ { "add" : { "index" : "things-v2", "alias" : "things" } } ] }
Written on November 30, 2017