You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch Painless中「Number」是否属于受限保留关键字?

问题:Elasticsearch 6.8 Painless脚本使用Number作为变量名编译报错

我使用Elasticsearch Painless脚本已有两年时间,近期在6.8版本的Elasticsearch中遇到异常问题:当在Painless脚本中使用首字母大写的「Number」作为变量名时会触发编译报错,全小写的「number」以及「Numb」、「Numbe」等变量名变体均可正常使用。


复现场景

复现请求如下:

curl -X POST "http://localhost:9201/logs-my_app-default/_search?size=2&pretty" -H 'Content-Type: application/json' -d '{"_source": ["-1"],  "script_fields": {"SCRIPT_FLAG": {"script": {"lang": "painless", "source": "  def Number = 0; "}}}}' 

问题出在代码行:def Number = 0;

抛出的错误信息如下:

"error" : {
    "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "compile error",
        "script_stack" : [
          "  def Number = 0; ",
          "      ^---- HERE"
        ],
        "script" : "  def Number = 0; ",
        "lang" : "painless"
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : "logs-my_app-default",
        "node" : "9jBNNKjdSIO6I8UH_HLVRw",
        "reason" : {
          "type" : "script_exception",
          "reason" : "compile error",
          "script_stack" : [
            "  def Number = 0; ",
            "      ^---- HERE"
          ],
          "script" : "  def Number = 0; ",
          "lang" : "painless",
          "caused_by" : {
            "type" : "illegal_argument_exception",
            "reason" : "invalid sequence of tokens near ['Number'].",
            "caused_by" : {
              "type" : "no_viable_alt_exception",
              "reason" : null
            }
          }
        }
      }
    ]
  },
  "status" : 500
}

该问题在6.8版本Elasticsearch的任意索引上均会触发,本次复现使用的索引创建语句如下:

curl -X POST "localhost:9201/logs-my_app-default/_doc?pretty" -H 'Content-Type: application/json' -d'
{
  "@timestamp": "2099-05-06T16:21:15.000Z",
  "event": {
    "original": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736"
  }
}
'

对应索引的mapping配置查询语句和返回结果如下:

curl -X GET "localhost:9201/logs-my_app-default/_mapping?pretty"
{
  "logs-my_app-default" : {
    "mappings" : {
      "_doc" : {
        "properties" : {
          "@timestamp" : {
            "type" : "date"
          },
          "event" : {
            "properties" : {
              "original" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

触发原因

Number是Painless脚本的大小写敏感内置类名,属于保留标识符,不允许直接作为变量名使用,因此会触发编译错误。其余变体比如全小写的number、截断的Numb/Numbe都不属于保留标识符,因此可以正常使用。
所有和Painless内置关键字、内置类名重名的变量名,都会触发同类编译错误。


适配解决方案

推荐最佳实践:当需要定义的Painless变量名与内置关键字/类名重名时,为变量添加下划线前缀规避冲突,示例如下:

def _Number = 0; // 替代 def Number = 0
def _Void = 0;   // 替代 def Void = 0
def _System = 0; // 替代 def System = 0

也可根据业务含义调整变量命名,只要不与内置保留标识符完全一致即可。


内容的提问来源于stack exchange,提问作者Nikola Nikolovski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:27:04