Skip to content

Commit 301dcb6

Browse files
authored
Add Runtime Fields Contexts to Painless Execute API (#71374)
This change adds support for the 7 different runtime fields contexts to the Painless Execute API. Each context can accept the standard script input (source and params) along with a user-defined document and an index name to pull mappings from. The results depend on the output of the runtime field type. Closes #70467
1 parent 0a176fe commit 301dcb6

File tree

3 files changed

+472
-3
lines changed

3 files changed

+472
-3
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.elasticsearch.common.xcontent.XContentType;
5151
import org.elasticsearch.index.Index;
5252
import org.elasticsearch.index.IndexService;
53+
import org.elasticsearch.index.mapper.DateFieldMapper;
5354
import org.elasticsearch.index.mapper.ParsedDocument;
5455
import org.elasticsearch.index.mapper.SourceToParse;
5556
import org.elasticsearch.index.query.AbstractQueryBuilder;
@@ -60,12 +61,19 @@
6061
import org.elasticsearch.rest.BaseRestHandler;
6162
import org.elasticsearch.rest.RestRequest;
6263
import org.elasticsearch.rest.action.RestToXContentListener;
64+
import org.elasticsearch.script.BooleanFieldScript;
65+
import org.elasticsearch.script.DateFieldScript;
66+
import org.elasticsearch.script.DoubleFieldScript;
6367
import org.elasticsearch.script.FilterScript;
68+
import org.elasticsearch.script.GeoPointFieldScript;
69+
import org.elasticsearch.script.IpFieldScript;
70+
import org.elasticsearch.script.LongFieldScript;
6471
import org.elasticsearch.script.ScoreScript;
6572
import org.elasticsearch.script.Script;
6673
import org.elasticsearch.script.ScriptContext;
6774
import org.elasticsearch.script.ScriptService;
6875
import org.elasticsearch.script.ScriptType;
76+
import org.elasticsearch.script.StringFieldScript;
6977
import org.elasticsearch.threadpool.ThreadPool;
7078
import org.elasticsearch.transport.TransportService;
7179

@@ -105,7 +113,15 @@ public static class Request extends SingleShardRequest<Request> implements ToXCo
105113
static final Map<String, ScriptContext<?>> SUPPORTED_CONTEXTS = Map.of(
106114
"painless_test", PainlessTestScript.CONTEXT,
107115
"filter", FilterScript.CONTEXT,
108-
"score", ScoreScript.CONTEXT);
116+
"score", ScoreScript.CONTEXT,
117+
"boolean_field", BooleanFieldScript.CONTEXT,
118+
"date_field", DateFieldScript.CONTEXT,
119+
"double_field", DoubleFieldScript.CONTEXT,
120+
"geo_point_field", GeoPointFieldScript.CONTEXT,
121+
"ip_field", IpFieldScript.CONTEXT,
122+
"long_field", LongFieldScript.CONTEXT,
123+
"string_field", StringFieldScript.CONTEXT)
124+
;
109125

110126
static ScriptContext<?> fromScriptContextName(String name) {
111127
ScriptContext<?> scriptContext = SUPPORTED_CONTEXTS.get(name);
@@ -492,7 +508,7 @@ static Response innerShardOperation(Request request, ScriptService scriptService
492508
return prepareRamIndex(request, (context, leafReaderContext) -> {
493509
FilterScript.Factory factory = scriptService.compile(request.script, FilterScript.CONTEXT);
494510
FilterScript.LeafFactory leafFactory =
495-
factory.newFactory(request.getScript().getParams(), context.lookup());
511+
factory.newFactory(request.getScript().getParams(), context.lookup());
496512
FilterScript filterScript = leafFactory.newInstance(leafReaderContext);
497513
filterScript.setDocument(0);
498514
boolean result = filterScript.execute();
@@ -502,7 +518,7 @@ static Response innerShardOperation(Request request, ScriptService scriptService
502518
return prepareRamIndex(request, (context, leafReaderContext) -> {
503519
ScoreScript.Factory factory = scriptService.compile(request.script, ScoreScript.CONTEXT);
504520
ScoreScript.LeafFactory leafFactory =
505-
factory.newFactory(request.getScript().getParams(), context.lookup());
521+
factory.newFactory(request.getScript().getParams(), context.lookup());
506522
ScoreScript scoreScript = leafFactory.newInstance(leafReaderContext);
507523
scoreScript.setDocument(0);
508524

@@ -521,6 +537,69 @@ static Response innerShardOperation(Request request, ScriptService scriptService
521537
double result = scoreScript.execute(null);
522538
return new Response(result);
523539
}, indexService);
540+
} else if (scriptContext == BooleanFieldScript.CONTEXT) {
541+
return prepareRamIndex(request, (context, leafReaderContext) -> {
542+
BooleanFieldScript.Factory factory = scriptService.compile(request.script, BooleanFieldScript.CONTEXT);
543+
BooleanFieldScript.LeafFactory leafFactory =
544+
factory.newFactory("boolean_field", request.getScript().getParams(), context.lookup());
545+
BooleanFieldScript booleanFieldScript = leafFactory.newInstance(leafReaderContext);
546+
booleanFieldScript.runForDoc(0);
547+
return new Response(booleanFieldScript.asDocValues());
548+
}, indexService);
549+
} else if (scriptContext == DateFieldScript.CONTEXT) {
550+
return prepareRamIndex(request, (context, leafReaderContext) -> {
551+
DateFieldScript.Factory factory = scriptService.compile(request.script, DateFieldScript.CONTEXT);
552+
DateFieldScript.LeafFactory leafFactory = factory.newFactory("date_field",
553+
request.getScript().getParams(), context.lookup(), DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER);
554+
DateFieldScript dateFieldScript = leafFactory.newInstance(leafReaderContext);
555+
dateFieldScript.runForDoc(0);
556+
return new Response(dateFieldScript.asDocValues());
557+
}, indexService);
558+
} else if (scriptContext == DoubleFieldScript.CONTEXT) {
559+
return prepareRamIndex(request, (context, leafReaderContext) -> {
560+
DoubleFieldScript.Factory factory = scriptService.compile(request.script, DoubleFieldScript.CONTEXT);
561+
DoubleFieldScript.LeafFactory leafFactory =
562+
factory.newFactory("double_field", request.getScript().getParams(), context.lookup());
563+
DoubleFieldScript doubleFieldScript = leafFactory.newInstance(leafReaderContext);
564+
doubleFieldScript.runForDoc(0);
565+
return new Response(doubleFieldScript.asDocValues());
566+
}, indexService);
567+
} else if (scriptContext == GeoPointFieldScript.CONTEXT) {
568+
return prepareRamIndex(request, (context, leafReaderContext) -> {
569+
GeoPointFieldScript.Factory factory = scriptService.compile(request.script, GeoPointFieldScript.CONTEXT);
570+
GeoPointFieldScript.LeafFactory leafFactory =
571+
factory.newFactory("geo_point_field", request.getScript().getParams(), context.lookup());
572+
GeoPointFieldScript geoPointFieldScript = leafFactory.newInstance(leafReaderContext);
573+
geoPointFieldScript.runForDoc(0);
574+
return new Response(geoPointFieldScript.asDocValues());
575+
}, indexService);
576+
} else if (scriptContext == IpFieldScript.CONTEXT) {
577+
return prepareRamIndex(request, (context, leafReaderContext) -> {
578+
IpFieldScript.Factory factory = scriptService.compile(request.script, IpFieldScript.CONTEXT);
579+
IpFieldScript.LeafFactory leafFactory =
580+
factory.newFactory("ip_field", request.getScript().getParams(), context.lookup());
581+
IpFieldScript ipFieldScript = leafFactory.newInstance(leafReaderContext);
582+
ipFieldScript.runForDoc(0);
583+
return new Response(ipFieldScript.asDocValues());
584+
}, indexService);
585+
} else if (scriptContext == LongFieldScript.CONTEXT) {
586+
return prepareRamIndex(request, (context, leafReaderContext) -> {
587+
LongFieldScript.Factory factory = scriptService.compile(request.script, LongFieldScript.CONTEXT);
588+
LongFieldScript.LeafFactory leafFactory =
589+
factory.newFactory("long_field", request.getScript().getParams(), context.lookup());
590+
LongFieldScript longFieldScript = leafFactory.newInstance(leafReaderContext);
591+
longFieldScript.runForDoc(0);
592+
return new Response(longFieldScript.asDocValues());
593+
}, indexService);
594+
} else if (scriptContext == StringFieldScript.CONTEXT) {
595+
return prepareRamIndex(request, (context, leafReaderContext) -> {
596+
StringFieldScript.Factory factory = scriptService.compile(request.script, StringFieldScript.CONTEXT);
597+
StringFieldScript.LeafFactory leafFactory =
598+
factory.newFactory("string_field", request.getScript().getParams(), context.lookup());
599+
StringFieldScript stringFieldScript = leafFactory.newInstance(leafReaderContext);
600+
stringFieldScript.resultsForDoc(0);
601+
return new Response(stringFieldScript.asDocValues());
602+
}, indexService);
524603
} else {
525604
throw new UnsupportedOperationException("unsupported context [" + scriptContext.name + "]");
526605
}

0 commit comments

Comments
 (0)