Skip to content

Commit 261b92a

Browse files
committed
Runtime fields to expose _source and stored fields like other script fields
This commit exposes stored fields to runtime fields (through params._fields) and replaces the current way to access _source (source['field']) in favour of the documented way for all existing scripts: params._source .
1 parent d47d450 commit 261b92a

File tree

8 files changed

+28
-11
lines changed

8 files changed

+28
-11
lines changed

x-pack/plugin/runtime-fields/qa/rest/src/yamlRestTest/java/org/elasticsearch/xpack/runtimefields/rest/CoreTestsWithRuntimeFieldsIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ private static String painlessToLoadFromSource(String name, String type) {
166166
return null;
167167
}
168168
StringBuilder b = new StringBuilder();
169-
b.append("def v = source['").append(name).append("'];\n");
169+
b.append("def v = params._source.").append(name).append(";\n");
170170
b.append("if (v instanceof Iterable) {\n");
171171
b.append(" for (def vv : ((Iterable) v)) {\n");
172172
b.append(" if (vv != null) {\n");

x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
import org.apache.lucene.index.LeafReaderContext;
1010
import org.elasticsearch.index.fielddata.ScriptDocValues;
1111
import org.elasticsearch.script.AggregationScript;
12+
import org.elasticsearch.script.DynamicMap;
1213
import org.elasticsearch.script.ScriptCache;
1314
import org.elasticsearch.script.ScriptContext;
1415
import org.elasticsearch.search.lookup.LeafSearchLookup;
1516
import org.elasticsearch.search.lookup.SearchLookup;
17+
import org.elasticsearch.search.lookup.SourceLookup;
1618

19+
import java.util.HashMap;
1720
import java.util.Map;
21+
import java.util.function.Function;
1822

1923
import static org.elasticsearch.common.unit.TimeValue.timeValueMillis;
2024

@@ -45,13 +49,25 @@ public static <F> ScriptContext<F> newContext(String name, Class<F> factoryClass
4549
);
4650
}
4751

52+
private static final Map<String, Function<Object, Object>> PARAMS_FUNCTIONS = Map.of(
53+
"_source",
54+
value -> ((SourceLookup) value).loadSourceIfNeeded()
55+
);
56+
4857
private final Map<String, Object> params;
4958
private final LeafSearchLookup leafSearchLookup;
5059

5160
public AbstractScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
5261
this.leafSearchLookup = searchLookup.getLeafSearchLookup(ctx);
53-
// TODO how do other scripts get stored fields exposed? Through asMap? I don't see any getters for them.
54-
this.params = params;
62+
params = new HashMap<>(params);
63+
for (Map.Entry<String, Object> entry : leafSearchLookup.asMap().entrySet()) {
64+
// accessing doc_values through through params._doc and params.doc is deprecated in all existing script contexts,
65+
// it makes little sense to expose it deprecated for runtime fields
66+
if (entry.getKey().equals("_doc") == false && entry.getKey().equals("doc") == false) {
67+
params.put(entry.getKey(), entry.getValue());
68+
}
69+
}
70+
this.params = new DynamicMap(params, PARAMS_FUNCTIONS);
5571
}
5672

5773
/**
@@ -71,7 +87,7 @@ public final Map<String, Object> getParams() {
7187
/**
7288
* Expose the {@code _source} to the script.
7389
*/
74-
public final Map<String, Object> getSource() {
90+
protected final Map<String, Object> getSource() {
7591
return leafSearchLookup.source();
7692
}
7793

x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/10_keyword.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ setup:
1717
type: double
1818
node:
1919
type: keyword
20+
store: true
2021
day_of_week:
2122
type: runtime_script
2223
runtime_type: keyword
@@ -27,7 +28,7 @@ setup:
2728
type: runtime_script
2829
runtime_type: keyword
2930
script: |
30-
Instant instant = Instant.ofEpochMilli(source['timestamp']);
31+
Instant instant = Instant.ofEpochMilli(params._source.timestamp);
3132
ZonedDateTime dt = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
3233
emitValue(dt.dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ROOT));
3334
# Test fetching many values
@@ -45,7 +46,7 @@ setup:
4546
runtime_type: keyword
4647
script:
4748
source: |
48-
for (String node : doc['node']) {
49+
for (String node : params._fields.node.values) {
4950
emitValue(params.prefix + node);
5051
}
5152
params:

x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/20_long.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ setup:
3333
runtime_type: long
3434
script:
3535
source: |
36-
emitValue((long)(source['voltage'] * params.multiplier));
36+
emitValue((long)(params._source.voltage * params.multiplier));
3737
params:
3838
multiplier: 10
3939
# Test fetching many values

x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/30_double.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ setup:
3333
runtime_type: double
3434
script:
3535
source: |
36-
emitValue(source['voltage'] / params.max);
36+
emitValue(params._source.voltage / params.max);
3737
params:
3838
max: 5.8
3939
# Test fetching many values

x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/40_date.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ setup:
3333
runtime_type: date
3434
script:
3535
source: |
36-
Instant instant = Instant.ofEpochMilli(parse(source['timestamp']));
36+
Instant instant = Instant.ofEpochMilli(parse(params._source.timestamp));
3737
ZonedDateTime dt = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
3838
emitValue(toEpochMilli(dt.plus(1, ChronoUnit.DAYS)));
3939
# Test returning millis

x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/50_ip.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ setup:
2727
runtime_type: ip
2828
script:
2929
source: |
30-
String m = source["message"];
30+
String m = params._source.message;
3131
int end = m.indexOf(" ");
3232
emitValue(m.substring(0, end));
3333
# Test emitting many values

x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/60_boolean.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ setup:
3333
runtime_type: boolean
3434
script:
3535
source: |
36-
emitValue(source['voltage'] >= 5.0);
36+
emitValue(params._source.voltage >= 5.0);
3737
# Test many booleans
3838
big_vals:
3939
type: runtime_script

0 commit comments

Comments
 (0)