弹性搜索:如何编写多语句脚本?

Bin*_*ier 6 groovy elasticsearch

我将值存储在Elasticsearch索引中的文档中.
我需要对值进行一些日期操作,并返回一个布尔值以在过滤器中使用.
该脚本涵盖了几行,我无法运行它.

我已经编写了其他单一的脚本,但是我对Groovy知之甚少,而对弹性搜索却知之甚少.

我用脚本找到的每个样本都有一行,只有一行.

所以基本上我将如何采用这个完全有效的脚本

"script": {
    "script": "doc['state'].value == 'completed' && doc['lastStateUpdate'].value < doc['dueDate'].value"
    }
Run Code Online (Sandbox Code Playgroud)

把它变成某种东西

"script": {
    "script": "def isCompleted = doc['state'].value == 'completed' 
               def preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value
               return isCompleted && preSLA"
    }
Run Code Online (Sandbox Code Playgroud)

我并没有为创建一个表示逻辑的只写一个班轮的想法而疯狂,我可以看到更多这些内容下线,虽然这个是相对直接的,但"一个班轮"不会去削减它.

这里的替代方法是在文档被索引之前对文档进行一些预处理,并向其中添加额外的数据.然而,这有一个缺点,因为它相当不灵活,我们需要重新索引所有数据来改变这些聚合,我们宁愿不这样做.

Val*_*Val 14

您只需要用分号分隔每个语句:

"script": {
    "script": "isCompleted = doc['state'].value == 'completed'; preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value; return isCompleted && preSLA;"
    }
Run Code Online (Sandbox Code Playgroud)

但请确保不要在脚本字符串中添加换行符,因为它不是有效的JSON.


Iva*_*ski 8

如果要将脚本分成多行,则必须使用文档来替代脚本"""

`"query": {
    "function_score": {
      "script_score": {
        "script": {
          "lang": "painless",
          "source": """
            int total = 0;
            for (int i = 0; i < doc['goals'].length; ++i) {
              total += doc['goals'][i];
            }
            return total;
          """
        }
      }
    }
  }
}`
Run Code Online (Sandbox Code Playgroud)

更新:对于某些版本的Elasticsearch source应该替换为inline docs

  • 这只适用于 `Kibana` 控制台 https://www.elastic.co/guide/en/kibana/7.5/console-kibana.html,你不能在 `Postman` 中执行此操作 (4认同)