Reputation: 149
Hi I am new to elasticsearch 7.9 update mapping, I came accross a use case where I have to update a simple field mapping to an object mapping, before I apply the query I created a simple example to test my purpose, here is what I have as an initial index mapping:
{
"myindex" : {
"mappings" : {
"properties" : {
"flag" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
I want to update the field name flag to tag and add to it a nested field called id which will contain the value of the field flag of the initial index myindex, I did the following steps :
PUT mynewindex/_mapping
{
"properties" : {
"tag" : {
"properties": {
"id" : {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
}
}
}
}
POST _reindex
{
"source": {
"index": "myindex"
},
"dest": {
"index": "mynewindex"
},
"script": {
"source": "ctx._source.tag.id = ctx._source.remove(\"flag\")"
}
}
which gave me this error :
{
"error" : {
"root_cause" : [
{
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"ctx._source.tag.id = ctx._source.remove(\"flag\")",
" ^---- HERE"
],
"script" : "ctx._source.tag.id = ctx._source.remove(\"flag\")",
"lang" : "painless",
"position" : {
"offset" : 15,
"start" : 0,
"end" : 47
}
}
],
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"ctx._source.tag.id = ctx._source.remove(\"flag\")",
" ^---- HERE"
],
"script" : "ctx._source.tag.id = ctx._source.remove(\"flag\")",
"lang" : "painless",
"position" : {
"offset" : 15,
"start" : 0,
"end" : 47
},
"caused_by" : {
"type" : "null_pointer_exception",
"reason" : "Cannot invoke \"Object.getClass()\" because \"callArgs[0]\" is null"
}
},
"status" : 400
}
The painless script found here in elastic doc, as I expected the dot notation to work, any suggestions or workaround to make it work!
Upvotes: 0
Views: 856
Reputation: 319
Since tag is null it is giving null pointer, you have to create a map first.
Below should work
POST _reindex
{
"source": {
"index": "myindex"
},
"dest": {
"index": "mynewindex"
},
"script" : {
"source": """
if(ctx._source.tag == null) {
ctx._source.tag = new HashMap();
}
if(ctx._source.flag != null) {
ctx._source.tag.id = ctx._source.remove("flag")
}
""",
"lang": "painless"
}
}
Upvotes: 1