Native (Java) Scripts

edit

Sometimes groovy and expression aren’t enough. For those times you can implement a native script.

The best way to implement a native script is to write a plugin and install it. The plugin documentation has more information on how to write a plugin so that Elasticsearch will properly load it.

To register the actual script you’ll need to implement NativeScriptFactory to construct the script. The actual script will extend either AbstractExecutableScript or AbstractSearchScript. The second one is likely the most useful and has several helpful subclasses you can extend like AbstractLongSearchScript and AbstractDoubleSearchScript. Finally, your plugin should register the native script by implementing the ScriptPlugin interface.

If you squashed the whole thing into one class it’d look like:

public class MyNativeScriptPlugin extends Plugin implements ScriptPlugin {

    @Override
    public List<NativeScriptFactory> getNativeScripts() {
        return Collections.singletonList(new MyNativeScriptFactory());
    }

    public static class MyNativeScriptFactory implements NativeScriptFactory {
        @Override
        public ExecutableScript newScript(@Nullable Map<String, Object> params) {
            return new MyNativeScript();
        }
        @Override
        public boolean needsScores() {
            return false;
        }
        @Override
        public String getName() {
            return "my_script";
        }
    }

    public static class MyNativeScript extends AbstractDoubleSearchScript {
        @Override
        public double runAsDouble() {
            double a = (double) source().get("a");
            double b = (double) source().get("b");
            return a * b;
        }
    }
}

You can execute the script by specifying its lang as native, and the name of the script as the id:

POST /_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "body": "foo"
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
                "inline": "my_script",
                "lang" : "native"
            }
          }
        }
      ]
    }
  }
}