Search code examples
elasticsearchelasticsearch-painless

Painless Script in Elasticsearch: "Cannot cast from [int] to [def[]]" Error When Using String.format


I am trying to use a Painless script in Elasticsearch to format an integer with leading zeros. Here is the script I am using:

{
  "query": {
    "match_all": {}
  },
  "sort": {
    "_script": {
      "type": "string",
      "script": {
        "source": """
          int paddingWidth = 10;
          def value = doc['employee_code.keyword'].value;
          if (value == null) return "";
          boolean isNumeric = true;
          if (isNumeric) {
            int temp = 2;
            return String.format('%010d', temp);
          } else {
            return value;
          }
        """,
        "lang": "painless"
      },
      "order": "asc"
    }
  }
}

However, I am getting the following error:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "compile error",
        "script_stack" : [
          "... n String.format('%010d', temp);\n          } else { ...",
          "                             ^---- HERE"
        ],
        "script" : "\n          int paddingWidth = 10;\n          def value = doc['employee_code.keyword'].value;\n          if (value == null) return \"\";\n          boolean isNumeric = true;\n          if (isNumeric) {\n            int temp = 2;\n            return String.format('%010d', temp);\n          } else {\n            return value;\n          }\n        ",
        "lang" : "painless",
        "position" : {
          "offset" : 263,
          "start" : 238,
          "end" : 288
        }
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : "search_psr_core_index",
        "node" : "govZA-NHQyStPH2nWOujMQ",
        "reason" : {
          "type" : "script_exception",
          "reason" : "compile error",
          "script_stack" : [
            "... n String.format('%010d', temp);\n          } else { ...",
            "                             ^---- HERE"
          ],
          "script" : "\n          int paddingWidth = 10;\n          def value = doc['employee_code.keyword'].value;\n          if (value == null) return \"\";\n          boolean isNumeric = true;\n          if (isNumeric) {\n            int temp = 2;\n            return String.format('%010d', temp);\n          } else {\n            return value;\n          }\n        ",
          "lang" : "painless",
          "position" : {
            "offset" : 263,
            "start" : 238,
            "end" : 288
          },
          "caused_by" : {
            "type" : "class_cast_exception",
            "reason" : "Cannot cast from [int] to [def[]]."
          }
        }
      }
    ]
  },
  "status" : 400
}

Additional Information:

  1. Elasticsearch version: 7.x

I have tried to troubleshoot this error, but it seems related to how Painless handles string formatting. Any help or pointers would be greatly appreciated.


Solution

  • I think you should use this

    String.format('%010d', new def[] {temp})
    

    instead of

    String.format('%010d', temp);
    

    I think the problem is here, painless is not like java and format method takes an array of objects to insert. Since you are inserting directly and integer into format, it gives an error.

    Instead we can insert a single element array.