ElasticSearch:禁用Groovy的_score字段上的聚合

use*_*035 7 scripting groovy elasticsearch

我见过的每个例子(例如,ElasticSearch:_score字段上的聚合?)用于在_score字段上进行聚合或与之相关的聚合似乎需要使用脚本.出于安全原因,默认情况下ElasticSearch会禁用动态脚本,有没有办法在不借助将脚本文件加载到每个ES节点或重新启用动态脚本的情况下实现此目的?

我的原始聚合如下所示:

"aggs": {
    "terms_agg": {
        "terms": {
            "field": "field1",
            "order": {"max_score": "desc"}
        },
     "aggs": {
         "max_score": {
             "max": {"script": "_score"}
         },
         "top_terms": {
             "top_hits": {"size": 1}
         }
      }
}
Run Code Online (Sandbox Code Playgroud)

尝试将表达式指定为lang似乎不起作用,因为ES会抛出一个错误,指出只有在用于排序时才能访问该分数.我无法通过得分字段找出任何其他方法来订购我的桶.有人有主意吗?

编辑:为了澄清,我的限制是无法修改服务器端.即,作为ES安装或配置的一部分,我无法添加或编辑任何内容.

And*_*fan 0

一种可能的方法是使用其他可用的脚本选项。mvel除非启用动态脚本,否则似乎无法使用。而且,除非对脚本启用/禁用的更细粒度控制达到 1.6 版本,否则我认为不可能mvelgroovy.

我们留下默认启用的nativemustache(用于模板)。我不认为自定义脚本可以用 来完成mustache,如果可能的话我没有找到方法,我们只剩下native(Java)脚本了。

这是我对此的看法:

  • 创建一个实现NativeScriptFactory
package com.foo.script;

import java.util.Map;

import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.NativeScriptFactory;

public class MyScriptNativeScriptFactory implements NativeScriptFactory {

    @Override
    public ExecutableScript newScript(Map<String, Object> arg0) {
        return new MyScript();
    }

}
Run Code Online (Sandbox Code Playgroud)
  • 例如AbstractFloatSearchScript
package com.foo.script;

import java.io.IOException;

import org.elasticsearch.script.AbstractFloatSearchScript;

public class MyScript extends AbstractFloatSearchScript {

    @Override
    public float runAsFloat() {
        try {
            return score();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

}
Run Code Online (Sandbox Code Playgroud)
  • 或者,构建一个简单的 Maven 项目将所有内容结合在一起。pom.xml:
<properties>
    <elasticsearch.version>1.5.2</elasticsearch.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${elasticsearch.version}</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

<build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)
  • 构建它并获取生成的 jar 文件。
  • 将 jar 放入 [ES_folder]/lib 中
  • 编辑elasticsearch.yml并添加 script.native.my_script.type: com.foo.script.MyScriptNativeScriptFactory

  • 重启ES节点。

  • 在聚合中使用它:
{
  "aggs": {
    "max_score": {
      "max": {
        "script": "my_script",
        "lang": "native"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我上面的示例仅返回_score作为脚本,但当然,它可以用于更高级的场景。

编辑:如果不允许您触摸实例,那么我认为您没有任何选择。