mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-12 07:02:10 +00:00
Add support for parameters for runtime fields.
Original Pull Request #2677 Closes #2303
This commit is contained in:
parent
ed898431ab
commit
922c7dd4a7
@ -19,7 +19,7 @@ public record FailureDetails(Integer status, String errorMessage) {
|
||||
|
||||
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`.
|
||||
|
||||
The `type` parameter of the `ScriptData` constructir is not nullable any longer.
|
||||
The `type` parameter of the `ScriptData` constructor is not nullable any longer.
|
||||
|
||||
[[elasticsearch-migration-guide-5.1-5.2.deprecations]]
|
||||
== Deprecations
|
||||
|
@ -67,7 +67,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.RefreshPolicy;
|
||||
import org.springframework.data.elasticsearch.core.query.ScriptType;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.index.*;
|
||||
@ -1237,14 +1236,23 @@ class RequestConverter {
|
||||
Map<String, RuntimeField> runtimeMappings = new HashMap<>();
|
||||
query.getRuntimeFields().forEach(runtimeField -> {
|
||||
RuntimeField esRuntimeField = RuntimeField.of(rt -> {
|
||||
RuntimeField.Builder builder = rt
|
||||
RuntimeField.Builder rfb = rt
|
||||
.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
|
||||
String script = runtimeField.getScript();
|
||||
|
||||
if (script != null) {
|
||||
builder = builder.script(s -> s.inline(is -> is.source(script)));
|
||||
rfb
|
||||
.script(s -> s
|
||||
.inline(is -> {
|
||||
is.source(script);
|
||||
|
||||
if (runtimeField.getParams() != null) {
|
||||
is.params(TypeUtils.paramsMap(runtimeField.getParams()));
|
||||
}
|
||||
return is;
|
||||
}));
|
||||
}
|
||||
return builder;
|
||||
return rfb;
|
||||
});
|
||||
runtimeMappings.put(runtimeField.getName(), esRuntimeField);
|
||||
});
|
||||
@ -1393,14 +1401,23 @@ class RequestConverter {
|
||||
|
||||
Map<String, RuntimeField> runtimeMappings = new HashMap<>();
|
||||
query.getRuntimeFields()
|
||||
.forEach(runtimeField -> runtimeMappings.put(runtimeField.getName(), RuntimeField.of(runtimeFieldBuilder -> {
|
||||
runtimeFieldBuilder.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
|
||||
.forEach(runtimeField -> runtimeMappings.put(runtimeField.getName(), RuntimeField.of(rfb -> {
|
||||
rfb.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
|
||||
String script = runtimeField.getScript();
|
||||
|
||||
if (script != null) {
|
||||
runtimeFieldBuilder.script(s -> s.inline(is -> is.source(script)));
|
||||
rfb
|
||||
.script(s -> s
|
||||
.inline(is -> {
|
||||
is.source(script);
|
||||
|
||||
if (runtimeField.getParams() != null) {
|
||||
is.params(TypeUtils.paramsMap(runtimeField.getParams()));
|
||||
}
|
||||
return is;
|
||||
}));
|
||||
}
|
||||
return runtimeFieldBuilder;
|
||||
|
||||
return rfb;
|
||||
})));
|
||||
builder.runtimeMappings(runtimeMappings);
|
||||
}
|
||||
|
@ -18,12 +18,20 @@ package org.springframework.data.elasticsearch.client.elc;
|
||||
import co.elastic.clients.elasticsearch._types.*;
|
||||
import co.elastic.clients.elasticsearch._types.mapping.FieldType;
|
||||
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
|
||||
import co.elastic.clients.elasticsearch.core.search.*;
|
||||
import co.elastic.clients.elasticsearch.core.search.BoundaryScanner;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterEncoder;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterFragmenter;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterOrder;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterTagsSchema;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterType;
|
||||
import co.elastic.clients.elasticsearch.core.search.ScoreMode;
|
||||
import co.elastic.clients.elasticsearch.indices.IndexSettings;
|
||||
import co.elastic.clients.json.JsonData;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.time.Duration;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@ -31,10 +39,16 @@ import java.util.stream.Collectors;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.RefreshPolicy;
|
||||
import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.query.*;
|
||||
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.IndicesOptions;
|
||||
import org.springframework.data.elasticsearch.core.query.Order;
|
||||
import org.springframework.data.elasticsearch.core.query.Query;
|
||||
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
|
||||
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Utility to handle new Elasticsearch client type values.
|
||||
@ -438,4 +452,18 @@ final class TypeUtils {
|
||||
return settings != null ? IndexSettings.of(b -> b.withJson(new StringReader(Document.from(settings).toJson())))
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
static Map<String, JsonData> paramsMap(Map<String, Object> params) {
|
||||
|
||||
Assert.notNull(params, "params must not be null");
|
||||
|
||||
Map<String, JsonData> mappedParams = new LinkedHashMap<>();
|
||||
params.forEach((key, value) -> {
|
||||
mappedParams.put(key, JsonData.of(value));
|
||||
});
|
||||
return mappedParams;
|
||||
}
|
||||
}
|
||||
|
@ -31,14 +31,26 @@ import org.springframework.util.Assert;
|
||||
public class RuntimeField {
|
||||
|
||||
private final String name;
|
||||
/**
|
||||
* the type of the runtime field (long, keyword, etc.)
|
||||
*/
|
||||
private final String type;
|
||||
@Nullable private final String script;
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
@Nullable Map<String, Object> params;
|
||||
|
||||
public RuntimeField(String name, String type) {
|
||||
this(name, type, null);
|
||||
this(name, type, null, null);
|
||||
}
|
||||
|
||||
public RuntimeField(String name, String type, @Nullable String script) {
|
||||
public RuntimeField(String name, String type, String script) {
|
||||
this(name, type, script, null);
|
||||
}
|
||||
|
||||
public RuntimeField(String name, String type, @Nullable String script, @Nullable Map<String, Object> params) {
|
||||
|
||||
Assert.notNull(name, "name must not be null");
|
||||
Assert.notNull(type, "type must not be null");
|
||||
@ -46,6 +58,7 @@ public class RuntimeField {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.script = script;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@ -78,4 +91,12 @@ public class RuntimeField {
|
||||
public @Nullable String getScript() {
|
||||
return script;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
@Nullable
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core.query.scriptedandruntimefiel
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -251,6 +252,29 @@ public abstract class ScriptedAndRuntimeFieldsIntegrationTests {
|
||||
operations.save(entity);
|
||||
}
|
||||
|
||||
@Test // #2303
|
||||
@DisplayName("should use parameters for runtime fields in search queries")
|
||||
void shouldUseParametersForRuntimeFieldsInSearchQueries() {
|
||||
|
||||
insert("1", "item 1", 80.0);
|
||||
insert("2", "item 2", 90.0);
|
||||
|
||||
RuntimeField runtimeField = new RuntimeField(
|
||||
"priceWithTax",
|
||||
"double",
|
||||
"emit(doc['price'].value * params.tax)",
|
||||
Map.of("tax", 1.19)
|
||||
);
|
||||
var query = CriteriaQuery.builder(
|
||||
Criteria.where("priceWithTax").greaterThan(100.0))
|
||||
.withRuntimeFields(List.of(runtimeField))
|
||||
.build();
|
||||
|
||||
var searchHits = operations.search(query, SomethingToBuy.class);
|
||||
|
||||
assertThat(searchHits).hasSize(1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Document(indexName = "#{@indexNameProvider.indexName()}-something-to-by")
|
||||
private static class SomethingToBuy {
|
||||
@ -386,13 +410,13 @@ public abstract class ScriptedAndRuntimeFieldsIntegrationTests {
|
||||
|
||||
@org.springframework.data.elasticsearch.annotations.Query("""
|
||||
{
|
||||
"term": {
|
||||
"value": {
|
||||
"value": "?0"
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"term": {
|
||||
"value": {
|
||||
"value": "?0"
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
SearchHits<SAREntity> findWithScriptedFields(Integer value,
|
||||
org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField1,
|
||||
org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField2);
|
||||
@ -401,13 +425,13 @@ public abstract class ScriptedAndRuntimeFieldsIntegrationTests {
|
||||
|
||||
@org.springframework.data.elasticsearch.annotations.Query("""
|
||||
{
|
||||
"term": {
|
||||
"value": {
|
||||
"value": "?0"
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"term": {
|
||||
"value": {
|
||||
"value": "?0"
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
SearchHits<SAREntity> findWithRuntimeFields(Integer value, RuntimeField runtimeField1, RuntimeField runtimeField2);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user