From 475e01f7591db8b9b6d33897ae46fe2362aa7217 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Wed, 7 Oct 2015 11:59:05 -0400 Subject: [PATCH] [doc] Rewrite native script documentation Closes #13811 --- docs/reference/modules/scripting.asciidoc | 94 ++++++++++++++++++----- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/docs/reference/modules/scripting.asciidoc b/docs/reference/modules/scripting.asciidoc index 7b2e43cd7de..50be5fdce48 100644 --- a/docs/reference/modules/scripting.asciidoc +++ b/docs/reference/modules/scripting.asciidoc @@ -351,28 +351,86 @@ to `false`. [float] === Native (Java) Scripts -Even though `groovy` is pretty fast, this allows to register native Java based -scripts for faster execution. +Sometimes `groovy` and `expressions` aren't enough. For those times you can +implement a native script. -In order to allow for scripts, the `NativeScriptFactory` needs to be -implemented that constructs the script that will be executed. There are -two main types, one that extends `AbstractExecutableScript` and one that -extends `AbstractSearchScript` (probably the one most users will extend, -with additional helper classes in `AbstractLongSearchScript`, -`AbstractDoubleSearchScript`, and `AbstractFloatSearchScript`). +The best way to implement a native script is to write a plugin and install it. +The plugin {plugins}/plugin-authors.html[documentation] has more information on +how to write a plugin so that Elasticsearch will properly load it. -Registering them can either be done by settings, for example: -`script.native.my.type` set to `sample.MyNativeScriptFactory` will -register a script named `my`. Another option is in a plugin, access -`ScriptModule` and call `registerScript` on 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`, `AbstractDoubleSearchScript`, and +`AbstractFloatSearchScript`. Finally, your plugin should register the native +script by declaring the `onModule(ScriptModule)` method. -Executing the script is done by specifying the `lang` as `native`, and -the name of the script as the `script`. +If you squashed the whole thing into one class it'd look like: + +[source,java] +-------------------------------------------------- +public class MyNativeScriptPlugin extends Plugin { + @Override + public String name() { + return "my-native-script"; + } + @Override + public String description() { + return "my native script that does something great"; + } + public void onModule(ScriptModule scriptModule) { + scriptModule.registerScript("my_script", MyNativeScriptFactory.class); + } + + public static class MyNativeScriptFactory implements NativeScriptFactory { + @Override + public ExecutableScript newScript(@Nullable Map params) { + return new MyNativeScript(); + } + @Override + public boolean needsScores() { + return false; + } + } + + public static class MyNativeScript extends AbstractFloatSearchScript { + @Override + public float runAsFloat() { + float a = (float) source().get("a"); + float b = (float) 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`: + +[source,js] +-------------------------------------------------- +curl -XPOST localhost:9200/_search -d '{ + "query": { + "function_score": { + "query": { + "match": { + "body": "foo" + } + }, + "functions": [ + { + "script_score": { + "id": "my_script", + "lang" : "native" + } + } + ] + } + } +}' +-------------------------------------------------- -Note, the scripts need to be in the classpath of elasticsearch. One -simple way to do it is to create a directory under plugins (choose a -descriptive name), and place the jar / classes files there. They will be -automatically loaded. [float] === Lucene Expressions Scripts