Skip to content

Commit 922c7dd

Browse files
authored
Add support for parameters for runtime fields.
Original Pull Request #2677 Closes #2303
1 parent ed89843 commit 922c7dd

File tree

5 files changed

+118
-28
lines changed

5 files changed

+118
-28
lines changed

src/main/asciidoc/reference/elasticsearch-migration-guide-5.1-5.2.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public record FailureDetails(Integer status, String errorMessage) {
1919

2020
The classes `org.springframework.data.elasticsearch.core.RuntimeField` and `org.springframework.data.elasticsearch.core.query.ScriptType` have been moved to the subpackage `org.springframework.data.elasticsearch.core.query`.
2121

22-
The `type` parameter of the `ScriptData` constructir is not nullable any longer.
22+
The `type` parameter of the `ScriptData` constructor is not nullable any longer.
2323

2424
[[elasticsearch-migration-guide-5.1-5.2.deprecations]]
2525
== Deprecations

src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
import org.springframework.dao.InvalidDataAccessApiUsageException;
6868
import org.springframework.data.domain.Sort;
6969
import org.springframework.data.elasticsearch.core.RefreshPolicy;
70-
import org.springframework.data.elasticsearch.core.query.ScriptType;
7170
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
7271
import org.springframework.data.elasticsearch.core.document.Document;
7372
import org.springframework.data.elasticsearch.core.index.*;
@@ -1237,14 +1236,23 @@ public MsearchRequest searchMsearchRequest(
12371236
Map<String, RuntimeField> runtimeMappings = new HashMap<>();
12381237
query.getRuntimeFields().forEach(runtimeField -> {
12391238
RuntimeField esRuntimeField = RuntimeField.of(rt -> {
1240-
RuntimeField.Builder builder = rt
1239+
RuntimeField.Builder rfb = rt
12411240
.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
12421241
String script = runtimeField.getScript();
12431242

12441243
if (script != null) {
1245-
builder = builder.script(s -> s.inline(is -> is.source(script)));
1244+
rfb
1245+
.script(s -> s
1246+
.inline(is -> {
1247+
is.source(script);
1248+
1249+
if (runtimeField.getParams() != null) {
1250+
is.params(TypeUtils.paramsMap(runtimeField.getParams()));
1251+
}
1252+
return is;
1253+
}));
12461254
}
1247-
return builder;
1255+
return rfb;
12481256
});
12491257
runtimeMappings.put(runtimeField.getName(), esRuntimeField);
12501258
});
@@ -1393,14 +1401,23 @@ private <T> void prepareSearchRequest(Query query, @Nullable String routing, @Nu
13931401

13941402
Map<String, RuntimeField> runtimeMappings = new HashMap<>();
13951403
query.getRuntimeFields()
1396-
.forEach(runtimeField -> runtimeMappings.put(runtimeField.getName(), RuntimeField.of(runtimeFieldBuilder -> {
1397-
runtimeFieldBuilder.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
1404+
.forEach(runtimeField -> runtimeMappings.put(runtimeField.getName(), RuntimeField.of(rfb -> {
1405+
rfb.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
13981406
String script = runtimeField.getScript();
1399-
14001407
if (script != null) {
1401-
runtimeFieldBuilder.script(s -> s.inline(is -> is.source(script)));
1408+
rfb
1409+
.script(s -> s
1410+
.inline(is -> {
1411+
is.source(script);
1412+
1413+
if (runtimeField.getParams() != null) {
1414+
is.params(TypeUtils.paramsMap(runtimeField.getParams()));
1415+
}
1416+
return is;
1417+
}));
14021418
}
1403-
return runtimeFieldBuilder;
1419+
1420+
return rfb;
14041421
})));
14051422
builder.runtimeMappings(runtimeMappings);
14061423
}

src/main/java/org/springframework/data/elasticsearch/client/elc/TypeUtils.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,37 @@
1818
import co.elastic.clients.elasticsearch._types.*;
1919
import co.elastic.clients.elasticsearch._types.mapping.FieldType;
2020
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
21-
import co.elastic.clients.elasticsearch.core.search.*;
21+
import co.elastic.clients.elasticsearch.core.search.BoundaryScanner;
22+
import co.elastic.clients.elasticsearch.core.search.HighlighterEncoder;
23+
import co.elastic.clients.elasticsearch.core.search.HighlighterFragmenter;
24+
import co.elastic.clients.elasticsearch.core.search.HighlighterOrder;
25+
import co.elastic.clients.elasticsearch.core.search.HighlighterTagsSchema;
26+
import co.elastic.clients.elasticsearch.core.search.HighlighterType;
27+
import co.elastic.clients.elasticsearch.core.search.ScoreMode;
2228
import co.elastic.clients.elasticsearch.indices.IndexSettings;
29+
import co.elastic.clients.json.JsonData;
2330

2431
import java.io.StringReader;
2532
import java.time.Duration;
2633
import java.util.EnumSet;
34+
import java.util.LinkedHashMap;
2735
import java.util.List;
2836
import java.util.Map;
2937
import java.util.stream.Collectors;
3038

3139
import org.springframework.data.domain.Sort;
3240
import org.springframework.data.elasticsearch.core.RefreshPolicy;
3341
import org.springframework.data.elasticsearch.core.document.Document;
34-
import org.springframework.data.elasticsearch.core.query.*;
42+
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
43+
import org.springframework.data.elasticsearch.core.query.IndexQuery;
3544
import org.springframework.data.elasticsearch.core.query.IndicesOptions;
45+
import org.springframework.data.elasticsearch.core.query.Order;
46+
import org.springframework.data.elasticsearch.core.query.Query;
47+
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
48+
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
3649
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
3750
import org.springframework.lang.Nullable;
51+
import org.springframework.util.Assert;
3852

3953
/**
4054
* Utility to handle new Elasticsearch client type values.
@@ -438,4 +452,18 @@ static IndexSettings indexSettings(@Nullable Map<String, Object> settings) {
438452
return settings != null ? IndexSettings.of(b -> b.withJson(new StringReader(Document.from(settings).toJson())))
439453
: null;
440454
}
455+
456+
/**
457+
* @since 5.2
458+
*/
459+
static Map<String, JsonData> paramsMap(Map<String, Object> params) {
460+
461+
Assert.notNull(params, "params must not be null");
462+
463+
Map<String, JsonData> mappedParams = new LinkedHashMap<>();
464+
params.forEach((key, value) -> {
465+
mappedParams.put(key, JsonData.of(value));
466+
});
467+
return mappedParams;
468+
}
441469
}

src/main/java/org/springframework/data/elasticsearch/core/query/RuntimeField.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,34 @@
3131
public class RuntimeField {
3232

3333
private final String name;
34+
/**
35+
* the type of the runtime field (long, keyword, etc.)
36+
*/
3437
private final String type;
3538
@Nullable private final String script;
3639

40+
/**
41+
* @since 5.2
42+
*/
43+
@Nullable Map<String, Object> params;
44+
3745
public RuntimeField(String name, String type) {
38-
this(name, type, null);
46+
this(name, type, null, null);
3947
}
4048

41-
public RuntimeField(String name, String type, @Nullable String script) {
49+
public RuntimeField(String name, String type, String script) {
50+
this(name, type, script, null);
51+
}
52+
53+
public RuntimeField(String name, String type, @Nullable String script, @Nullable Map<String, Object> params) {
4254

4355
Assert.notNull(name, "name must not be null");
4456
Assert.notNull(type, "type must not be null");
4557

4658
this.name = name;
4759
this.type = type;
4860
this.script = script;
61+
this.params = params;
4962
}
5063

5164
public String getName() {
@@ -78,4 +91,12 @@ public String getType() {
7891
public @Nullable String getScript() {
7992
return script;
8093
}
94+
95+
/**
96+
* @since 5.2
97+
*/
98+
@Nullable
99+
public Map<String, Object> getParams() {
100+
return params;
101+
}
81102
}

src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ScriptedAndRuntimeFieldsIntegrationTests.java

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.assertj.core.api.Assertions.*;
1919

2020
import java.time.LocalDate;
21+
import java.util.List;
2122
import java.util.Map;
2223

2324
import org.jetbrains.annotations.NotNull;
@@ -251,6 +252,29 @@ private void insert(String id, String description, double price) {
251252
operations.save(entity);
252253
}
253254

255+
@Test // #2303
256+
@DisplayName("should use parameters for runtime fields in search queries")
257+
void shouldUseParametersForRuntimeFieldsInSearchQueries() {
258+
259+
insert("1", "item 1", 80.0);
260+
insert("2", "item 2", 90.0);
261+
262+
RuntimeField runtimeField = new RuntimeField(
263+
"priceWithTax",
264+
"double",
265+
"emit(doc['price'].value * params.tax)",
266+
Map.of("tax", 1.19)
267+
);
268+
var query = CriteriaQuery.builder(
269+
Criteria.where("priceWithTax").greaterThan(100.0))
270+
.withRuntimeFields(List.of(runtimeField))
271+
.build();
272+
273+
var searchHits = operations.search(query, SomethingToBuy.class);
274+
275+
assertThat(searchHits).hasSize(1);
276+
}
277+
254278
@SuppressWarnings("unused")
255279
@Document(indexName = "#{@indexNameProvider.indexName()}-something-to-by")
256280
private static class SomethingToBuy {
@@ -386,13 +410,13 @@ SearchHits<SAREntity> findByValue(Integer value,
386410

387411
@org.springframework.data.elasticsearch.annotations.Query("""
388412
{
389-
"term": {
390-
"value": {
391-
"value": "?0"
392-
}
393-
}
394-
}
395-
""")
413+
"term": {
414+
"value": {
415+
"value": "?0"
416+
}
417+
}
418+
}
419+
""")
396420
SearchHits<SAREntity> findWithScriptedFields(Integer value,
397421
org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField1,
398422
org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField2);
@@ -401,13 +425,13 @@ SearchHits<SAREntity> findWithScriptedFields(Integer value,
401425

402426
@org.springframework.data.elasticsearch.annotations.Query("""
403427
{
404-
"term": {
405-
"value": {
406-
"value": "?0"
407-
}
408-
}
409-
}
410-
""")
428+
"term": {
429+
"value": {
430+
"value": "?0"
431+
}
432+
}
433+
}
434+
""")
411435
SearchHits<SAREntity> findWithRuntimeFields(Integer value, RuntimeField runtimeField1, RuntimeField runtimeField2);
412436
}
413437
}

0 commit comments

Comments
 (0)