Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
771 views
in Technique[技术] by (71.8m points)

elasticsearch - Update mapping of an index from a simple mapping to an object mapping

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 :

  1. created the new index mynewindex with the following mapping :
PUT mynewindex/_mapping
{
"properties" : {
        "tag" : {
          "properties": {
            "id" : {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
}
  1. and use reindex API:
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!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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"
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...