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



我在Elasticsearch索引中的文档中存储了值
我需要对这些值进行一些日期操作,并返回一个要在过滤器中使用的布尔值
这个剧本有好几行,我无法让它运行。

我还写过其他运行良好的脚本,但我对Groovy知之甚少,对Elastic搜索知之甚少。

我能用脚本找到的每个样本都有一行,而且只有一行。

那么基本上我该如何使用这个完全有效的脚本

"script": {
    "script": "doc['state'].value == 'completed' && doc['lastStateUpdate'].value < doc['dueDate'].value"
    }

把它变成

"script": {
    "script": "def isCompleted = doc['state'].value == 'completed' 
               def preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value
               return isCompleted && preSLA"
    }

我对创建一个只写一行来表达逻辑的想法并不生气,我可以看到更多这样的行,虽然这一行相对简单,但"一行"不会削减它。

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

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

"script": {
    "script": "isCompleted = doc['state'].value == 'completed'; preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value; return isCompleted && preSLA;"
    }

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

如果你想把你的脚本分成多行,你必须用"""文档代替你的脚本

`"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;
          """
        }
      }
    }
  }
}`

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

最新更新