无痛调试

编辑

Debug.Explain

编辑

Painless 没有 REPL,虽然未来拥有它会很棒,但它并不能完全解决 Elasticsearch 中嵌入式 Painless 脚本的调试问题,因为脚本可访问的数据或“上下文”非常重要。目前,调试嵌入式脚本的最佳方法是在适当的位置抛出异常。虽然您可以抛出自己的异常(throw new Exception('whatever')),但 Painless 的沙箱会阻止您访问有用的信息,例如对象的类型。因此,Painless 有一个实用程序方法 Debug.explain,它可以为您抛出异常。例如,您可以使用 _explain 来探索可用于 脚本查询 的上下文。

PUT /hockey/_doc/1?refresh
{"first":"johnny","last":"gaudreau","goals":[9,27,1],"assists":[17,46,0],"gp":[26,82,1]}

POST /hockey/_explain/1
{
  "query": {
    "script": {
      "script": "Debug.explain(doc.goals)"
    }
  }
}

这将通过响应显示 doc.first 的类是 org.elasticsearch.index.fielddata.ScriptDocValues.Longs

{
   "error": {
      "type": "script_exception",
      "to_string": "[1, 9, 27]",
      "painless_class": "org.elasticsearch.index.fielddata.ScriptDocValues.Longs",
      "java_class": "org.elasticsearch.index.fielddata.ScriptDocValues$Longs",
      ...
   },
   "status": 400
}

您可以使用相同的技巧查看 _source_update API 中是 LinkedHashMap

POST /hockey/_update/1
{
  "script": "Debug.explain(ctx._source)"
}

响应如下所示:

{
  "error" : {
    "root_cause": ...,
    "type": "illegal_argument_exception",
    "reason": "failed to execute script",
    "caused_by": {
      "type": "script_exception",
      "to_string": "{gp=[26, 82, 1], last=gaudreau, assists=[17, 46, 0], first=johnny, goals=[9, 27, 1]}",
      "painless_class": "java.util.LinkedHashMap",
      "java_class": "java.util.LinkedHashMap",
      ...
    }
  },
  "status": 400
}

获得类之后,您可以访问 Painless API 参考 以查看可用方法的列表。