2016-05-04 12:17:10 -04:00
|
|
|
[[modules-scripting-native]]
|
|
|
|
=== Native (Java) Scripts
|
|
|
|
|
2016-11-22 22:24:12 -05:00
|
|
|
Sometimes `painless` and <<modules-scripting-expression, expression>> aren't enough. For those times you can
|
2016-05-04 12:17:10 -04:00
|
|
|
implement a native script.
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
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
|
2016-05-15 22:59:28 -04:00
|
|
|
`AbstractLongSearchScript` and `AbstractDoubleSearchScript`.
|
2016-11-17 11:22:15 -05:00
|
|
|
Finally, your plugin should register the native script by implementing the
|
|
|
|
`ScriptPlugin` interface.
|
2016-05-04 12:17:10 -04:00
|
|
|
|
|
|
|
If you squashed the whole thing into one class it'd look like:
|
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
2016-11-10 18:52:17 -05:00
|
|
|
public class MyNativeScriptPlugin extends Plugin implements ScriptPlugin {
|
|
|
|
|
2016-05-04 12:17:10 -04:00
|
|
|
@Override
|
2016-11-10 18:52:17 -05:00
|
|
|
public List<NativeScriptFactory> getNativeScripts() {
|
|
|
|
return Collections.singletonList(new MyNativeScriptFactory());
|
2016-05-04 12:17:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public static class MyNativeScriptFactory implements NativeScriptFactory {
|
|
|
|
@Override
|
|
|
|
public ExecutableScript newScript(@Nullable Map<String, Object> params) {
|
|
|
|
return new MyNativeScript();
|
|
|
|
}
|
|
|
|
@Override
|
|
|
|
public boolean needsScores() {
|
|
|
|
return false;
|
|
|
|
}
|
2016-12-29 12:21:32 -05:00
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return "my_script";
|
|
|
|
}
|
2016-05-04 12:17:10 -04:00
|
|
|
}
|
|
|
|
|
2016-05-15 22:59:28 -04:00
|
|
|
public static class MyNativeScript extends AbstractDoubleSearchScript {
|
2016-05-04 12:17:10 -04:00
|
|
|
@Override
|
2016-05-15 22:59:28 -04:00
|
|
|
public double runAsDouble() {
|
|
|
|
double a = (double) source().get("a");
|
|
|
|
double b = (double) source().get("b");
|
2016-05-04 12:17:10 -04:00
|
|
|
return a * b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
You can execute the script by specifying its `lang` as `native`, and the name
|
|
|
|
of the script as the `id`:
|
|
|
|
|
2017-02-08 11:14:17 -05:00
|
|
|
|
2016-05-04 12:17:10 -04:00
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
2017-02-08 11:14:17 -05:00
|
|
|
POST /_search
|
|
|
|
{
|
2016-05-04 12:17:10 -04:00
|
|
|
"query": {
|
|
|
|
"function_score": {
|
|
|
|
"query": {
|
|
|
|
"match": {
|
|
|
|
"body": "foo"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"functions": [
|
|
|
|
{
|
|
|
|
"script_score": {
|
|
|
|
"script": {
|
2016-12-29 12:21:32 -05:00
|
|
|
"inline": "my_script",
|
2016-05-04 12:17:10 -04:00
|
|
|
"lang" : "native"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
2017-02-08 11:14:17 -05:00
|
|
|
}
|
2016-05-04 12:17:10 -04:00
|
|
|
--------------------------------------------------
|
2017-02-08 11:14:17 -05:00
|
|
|
// CONSOLE
|
|
|
|
// TEST[skip:we don't have a native plugin installed to test this]
|