seba_sencha
seba_sencha

Reputation: 205

Renaming fields in elasticsearch

I have a document like this

{
    "_index": "testindex",
    "_type": "logs",
    "_id": "1",
    "_score": 1,
    "_source": {
      "field1": "data1",
      "field2": "data2"
    }
}

I need to change the field2 to Request.field3

{
    "_index": "testindex",
    "_type": "logs",
    "_id": "1",
    "_score": 1,
    "_source": {
      "field1": "data1",
      "Request": {
        "field3": "data2"
      }
    }
}

For this, first added a field mapping to existing index

PUT testindex/_mapping/logs
{
    "properties": 
    { 
        "Request": 
        {
            "properties": 
            {
                "field3" : 
                {
                    "type": "string"
                }
            }
        }   
    }  
}

Then tried reindexing

POST _reindex
{
    "source": {
        "index": "testindex"
    },
    "dest": {
        "index": "testindex1"
    },
    "script": {
        "inline": "ctx._source.Request.field3 = ctx._source.remove(\"field2\")"
    }
}

Error is

"reason": "failed to run inline script [ctx._source.Request.field3 = ctx._source.remove(\"field2\")] using lang [groovy]",
"caused_by": {
    "type": "null_pointer_exception",
    "reason": "Cannot set property 'field3' on null object"
}

Upvotes: 8

Views: 10176

Answers (2)

Pramod H G
Pramod H G

Reputation: 1613

The easiest way to rename the field name is to use the _update_by_query API:

Example: POST http://localhost:9200/INDEX_NAME/_update_by_query

{
  "query": { 
    "bool": {
        "must_not": {
            "exists": {
                "field": "NEW_FIELD_NAME"
            }
        }
    }
  },
  "script" : {
    "inline": "ctx._source.NEW_FIELD_NAME = ctx._source.OLD_FIELD_NAME; ctx._source.remove(\"OLD_FIELD_NAME\");"
  }
}

Upvotes: 2

Val
Val

Reputation: 217464

The Request field does not yet exist in your documents, so your script needs to create it first:

POST _reindex
{
    "source": {
        "index": "testindex"
    },
    "dest": {
        "index": "testindex1"
    },
    "script": {
        "inline": "ctx._source.Request = [:]; ctx._source.Request.field3 = ctx._source.remove(\"field2\") ]"
    }
}

Or a bit shorter like this:

POST _reindex
{
    "source": {
        "index": "testindex"
    },
    "dest": {
        "index": "testindex1"
    },
    "script": {
        "inline": "ctx._source.Request = [field3: ctx._source.remove(\"field2\") ]"
    }
}

Upvotes: 22

Related Questions