Skip to content

Commit ee59e15

Browse files
committed
Scripting: Replace advanced and native scripts with ScriptEngine docs (#24603)
This commit documents how to write a `ScriptEngine` in order to use expert internal apis, such as using Lucene directly to find index term statistics. These documents prepare the way to remove both native scripts and IndexLookup. The example java code is actually compiled and tested under a new gradle subproject for example plugins. This change does not yet breakup jvm-example into the new examples dir, which should be done separately. relates #19359 relates #19966
1 parent 39ad671 commit ee59e15

File tree

14 files changed

+395
-285
lines changed

14 files changed

+395
-285
lines changed

core/src/main/java/org/elasticsearch/script/LeafSearchScript.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,30 @@
1919

2020
package org.elasticsearch.script;
2121

22+
import org.apache.lucene.search.Scorer;
2223
import org.elasticsearch.common.lucene.ScorerAware;
2324

2425
import java.util.Map;
2526

2627
/**
2728
* A per-segment {@link SearchScript}.
29+
*
30+
* This is effectively a functional interface, requiring at least implementing {@link #runAsDouble()}.
2831
*/
2932
public interface LeafSearchScript extends ScorerAware, ExecutableScript {
3033

31-
void setDocument(int doc);
34+
/**
35+
* Set the document this script will process next.
36+
*/
37+
default void setDocument(int doc) {}
38+
39+
@Override
40+
default void setScorer(Scorer scorer) {}
3241

33-
void setSource(Map<String, Object> source);
42+
/**
43+
* Set the source for the current document.
44+
*/
45+
default void setSource(Map<String, Object> source) {}
3446

3547
/**
3648
* Sets per-document aggregation {@code _value}.
@@ -44,8 +56,23 @@ default void setNextAggregationValue(Object value) {
4456
setNextVar("_value", value);
4557
}
4658

47-
long runAsLong();
59+
@Override
60+
default void setNextVar(String field, Object value) {}
4861

49-
double runAsDouble();
62+
/**
63+
* Return the result as a long. This is used by aggregation scripts over long fields.
64+
*/
65+
default long runAsLong() {
66+
throw new UnsupportedOperationException("runAsLong is not implemented");
67+
}
68+
69+
@Override
70+
default Object run() {
71+
return runAsDouble();
72+
}
5073

74+
/**
75+
* Return the result as a double. This is the main use case of search script, used for document scoring.
76+
*/
77+
double runAsDouble();
5178
}

core/src/main/java/org/elasticsearch/script/ScriptEngineService.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ public interface ScriptEngineService extends Closeable {
3232

3333
String getType();
3434

35-
String getExtension();
35+
/**
36+
* The extension for file scripts in this language.
37+
*/
38+
default String getExtension() {
39+
return getType();
40+
}
3641

3742
/**
3843
* Compiles a script.

docs/reference/modules/scripting.asciidoc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ certain tasks.
6363
|built-in
6464
|templates
6565

66-
|<<modules-scripting-native, `java`>>
66+
|<<modules-scripting-engine, `java`>>
6767
|n/a
6868
|you write it!
6969
|expert API
@@ -97,7 +97,4 @@ include::scripting/painless-debugging.asciidoc[]
9797

9898
include::scripting/expression.asciidoc[]
9999

100-
include::scripting/native.asciidoc[]
101-
102-
include::scripting/advanced-scripting.asciidoc[]
103-
100+
include::scripting/engine.asciidoc[]

docs/reference/modules/scripting/advanced-scripting.asciidoc

Lines changed: 0 additions & 189 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
[[modules-scripting-engine]]
2+
=== Advanced scripts using script engines
3+
4+
A `ScriptEngine` is a backend for implementing a scripting language. It may also
5+
be used to write scripts that need to use advanced internals of scripting. For example,
6+
a script that wants to use term frequencies while scoring.
7+
8+
The plugin {plugins}/plugin-authors.html[documentation] has more information on
9+
how to write a plugin so that Elasticsearch will properly load it. To register
10+
the `ScriptEngine`, your plugin should implement the `ScriptPlugin` interface
11+
and override the `getScriptEngine(Settings settings)` method.
12+
13+
The following is an example of a custom `ScriptEngine` which uses the language
14+
name `expert_scripts`. It implements a single script called `pure_df` which
15+
may be used as a search script to override each document's score as
16+
the document frequency of a provided term.
17+
18+
["source","java",subs="attributes,callouts,macros"]
19+
--------------------------------------------------
20+
include-tagged::{docdir}/../../plugins/examples/script-expert-scoring/src/main/java/org/elasticsearch/example/expertscript/ExpertScriptPlugin.java[expert_engine]
21+
--------------------------------------------------
22+
23+
You can execute the script by specifying its `lang` as `expert_scripts`, and the name
24+
of the script as the the script source:
25+
26+
27+
[source,js]
28+
--------------------------------------------------
29+
POST /_search
30+
{
31+
"query": {
32+
"function_score": {
33+
"query": {
34+
"match": {
35+
"body": "foo"
36+
}
37+
},
38+
"functions": [
39+
{
40+
"script_score": {
41+
"script": {
42+
"inline": "pure_df",
43+
"lang" : "expert_scripts",
44+
"params": {
45+
"field": "body",
46+
"term": "foo"
47+
}
48+
}
49+
}
50+
}
51+
]
52+
}
53+
}
54+
}
55+
--------------------------------------------------
56+
// CONSOLE
57+
// TEST[skip:we don't have an expert script plugin installed to test this]

0 commit comments

Comments
 (0)