Cast exception when trying to fill old data through re-indexing

Hi

I am try to fill a new field to my old data through re-indexing, but when i run below it's gives me below error. The status field is set to long from mapping. Please help me to resolve this.

 "caused_by": {
      "type": "class_cast_exception",
      "reason": "Cannot apply [>] operation to types [java.lang.String] and [java.lang.Integer]."
    }

    POST _reindex
{
  "source": {
    "index": "mapped_index_long"
  },
  "dest": {
    "index": "stage_mapped_index",
    "version_type": "external"
  },
   "script": {
    "lang": "painless",
    "source": "if (ctx._source.status >= 200 && ctx._source.status < 400) {\n  ctx._source.stage= \"Success\";\n} else {\n  ctx._source.stage=\"Failed\";\n}"                                                                          
  }
}

Thank you,
Rajith

The ctx._source value provides access to the actual indexed JSON document. The fact that it may be using a long mapping for field status only means that the value of the status field will be parsed as long while indexing but if that field carries a string then it will still remain as string value in the reindex script.

To fix that try parsing the ctx._source.status with Integer.parseInt static method prior to making the comparison.,

1 Like

Hi Thiago,

Thank you for your response. I tried to parse
int x = Integer.parseInt(ctx._source.status);
But now i'am getting
"reason": "Cannot cast java.lang.Integer to java.lang.String"

Thank you.

So seems like you have documents in which status can be either string or integer. You need to write a script to consider both cases.

Hi Thiago,

Thank you your inputs, finally managed to write a script to insert data. I am posting it below, hope it helps someone.

POST _reindex
{
  "source": {
    "index": "mapped_index_long"
  },
  "dest": {
    "index": "stage_mapped_index",
    "version_type": "external"
  },
   "script": {
    "lang": "painless",  
    "source": """
      if (ctx._source.status != "null") {
        int x = Integer.parseInt(String.valueOf(ctx._source.status));
        if (x >= 200 && x < 400) 
        {ctx._source.stage= "Success";} 
        else 
        {ctx._source.stage="Failed";}  
     }
      """                                                             
  }
}

That is almost good. Just change the null check to ctx._source.status != null which is probably what you meant.

1 Like

Thanks thiago, now it's working.