Elasticsearch is structureless by default – can add up any field / structure as to any document based DB (like Mongo), but then there is also option where to map up an index / type in elasticsearch.
Now dealing a change like name of the field is pretty easy with RDBMS – it deal in with all the behind the scene work. But the same is not a straight forward stuff with Elasticsearch. Though Elasticsearch have the mechanisms available for the same but it expects more to be dealt by end user himself.
A scenario – Say you have a table where you have a field named – topic. Now you want to change the name to topic_name. There is a simple operation available on the same,
POST topics/_update_by_query
{
"query": {
"constant_score" : {
"filter" : {
"exists" : { "field" : "topic" }
}
}
},
"script" : {
"inline": "ctx._source.topic_name = ctx._source.topic;"
}
}
What the above code will do is add the field topic_name and set the value – the same as the one of topic field.
But then we are stuck with one issue – we have topic field and topic_name field. The code will be designed to set the new rows to have topic_name and not topic. So the earlier rows will have an issue – there will be extra field (topic) which already existed. How to deal with it? Now there aint any methodologies provided by Elastisearch to delete an existing column (field) from all the rows across. Well, that too have been provided as using scripting.
POST topics/_update_by_query
{
"query": {
"constant_score" : {
"filter" : {
"exists" : { "field" : "topic" }
}
}
},
"script" : {
"inline": "ctx._source.remove(\"topic\");"
}
}
This way – you get the topic field removed. And you are left with just topic_name. With this above set pattern – you can update the index / mapping to have the field name changed as required.
Now but there is a catch to the same, i actually faced this one now. When we created the above, the structure technically changed. For – i wanted to have is remove the topic from mapping itself – and add topic_name as a keyword – which i can use to search. But what happened in there – it started failing .. with above .. why? when we performed that – what happened was it kept the topic as the field (which was set during the creation of mapping). Apart from it – what extra it did to the same was – it created topic_name as a text field (that’s noticed as a default behaviour of elasticsearch – its way to handle unmapped field). Due to the reason, the other queries that were working on fetching the data from topic – started failing with topic_name as it was of text type and not keyword type.
How to resolve this issue now? Well that i will continue in the other topic of mine – which will relate to restructuring of the mapping.