Upgrade to Elasticsearch 8.15.0.

Ortiginal Pull Request #2974
Closes #2963
This commit is contained in:
Peter-Josef Meisch 2024-08-30 21:31:07 +02:00 committed by GitHub
parent 6ad98bf500
commit 81eb167981
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 119 additions and 126 deletions

View File

@ -21,7 +21,7 @@
<springdata.commons>3.4.0-SNAPSHOT</springdata.commons> <springdata.commons>3.4.0-SNAPSHOT</springdata.commons>
<!-- version of the ElasticsearchClient --> <!-- version of the ElasticsearchClient -->
<elasticsearch-java>8.14.3</elasticsearch-java> <elasticsearch-java>8.15.0</elasticsearch-java>
<blockhound-junit>1.0.9.RELEASE</blockhound-junit> <blockhound-junit>1.0.9.RELEASE</blockhound-junit>
<hoverfly>0.19.0</hoverfly> <hoverfly>0.19.0</hoverfly>

View File

@ -4,7 +4,7 @@
[[new-features.5-4-0]] [[new-features.5-4-0]]
== New in Spring Data Elasticsearch 5.4 == New in Spring Data Elasticsearch 5.4
* Upgrade to Elasticsearch 8.14.3. * Upgrade to Elasticsearch 8.15.0.
* Allow to customize the mapped type name for `@InnerField` and `@Field` annotations. * Allow to customize the mapped type name for `@InnerField` and `@Field` annotations.
* Support for Elasticsearch SQL. * Support for Elasticsearch SQL.

View File

@ -6,7 +6,7 @@ The following table shows the Elasticsearch and Spring versions that are used by
[cols="^,^,^,^",options="header"] [cols="^,^,^,^",options="header"]
|=== |===
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework | Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
| 2024.1 (in development) | 5.3.x | 8.14.3 | 6.1.x | 2024.1 (in development) | 5.3.x | 8.15.0 | 6.1.x
| 2024.0 | 5.3.1 | 8.13.4 | 6.1.x | 2024.0 | 5.3.1 | 8.13.4 | 6.1.x
| 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x | 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x
| 2023.0 (Ullmann) | 5.1.x | 8.7.1 | 6.0.x | 2023.0 (Ullmann) | 5.1.x | 8.7.1 | 6.0.x

View File

@ -127,7 +127,7 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
mustQueries.add(Query.of(qb -> qb.matchAll(m -> m))); mustQueries.add(Query.of(qb -> qb.matchAll(m -> m)));
} }
return new Query.Builder().bool(boolQueryBuilder -> { return new Query.Builder().bool(boolQueryBuilder -> {
if (!shouldQueries.isEmpty()) { if (!shouldQueries.isEmpty()) {
boolQueryBuilder.should(shouldQueries); boolQueryBuilder.should(shouldQueries);
@ -249,49 +249,54 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
queryBuilder.queryString(queryStringQuery(fieldName, Objects.requireNonNull(value).toString(), boost)); queryBuilder.queryString(queryStringQuery(fieldName, Objects.requireNonNull(value).toString(), boost));
break; break;
case LESS: case LESS:
queryBuilder // queryBuilder
.range(rb -> rb // .range(rb -> rb
.field(fieldName) // .untyped(ut -> ut
.lt(JsonData.of(value)) // .field(fieldName)
.boost(boost)); // .lt(JsonData.of(value))
.boost(boost)));
break; break;
case LESS_EQUAL: case LESS_EQUAL:
queryBuilder // queryBuilder
.range(rb -> rb // .range(rb -> rb
.field(fieldName) // .untyped(ut -> ut
.lte(JsonData.of(value)) // .field(fieldName)
.boost(boost)); // .lte(JsonData.of(value))
.boost(boost)));
break; break;
case GREATER: case GREATER:
queryBuilder // queryBuilder
.range(rb -> rb // .range(rb -> rb
.field(fieldName) // .untyped(ut -> ut
.gt(JsonData.of(value)) // .field(fieldName)
.boost(boost)); // .gt(JsonData.of(value))
.boost(boost)));
break; break;
case GREATER_EQUAL: case GREATER_EQUAL:
queryBuilder // queryBuilder
.range(rb -> rb // .range(rb -> rb
.field(fieldName) // .untyped(ut -> ut
.gte(JsonData.of(value)) // .field(fieldName)
.boost(boost)); // .gte(JsonData.of(value))
.boost(boost)));
break; break;
case BETWEEN: case BETWEEN:
Object[] ranges = (Object[]) value; Object[] ranges = (Object[]) value;
Assert.notNull(value, "value for a between condition must not be null"); Assert.notNull(value, "value for a between condition must not be null");
queryBuilder // queryBuilder
.range(rb -> { .range(rb -> rb
rb.field(fieldName); .untyped(ut -> {
if (ranges[0] != null) { ut.field(fieldName);
rb.gte(JsonData.of(ranges[0])); if (ranges[0] != null) {
} ut.gte(JsonData.of(ranges[0]));
}
if (ranges[1] != null) { if (ranges[1] != null) {
rb.lte(JsonData.of(ranges[1])); ut.lte(JsonData.of(ranges[1]));
} }
rb.boost(boost); // ut.boost(boost); //
return rb; return ut;
}); // }));
break; break;
case FUZZY: case FUZZY:

View File

@ -126,7 +126,7 @@ public class ReactiveElasticsearchClient extends ApiClient<ElasticsearchTranspor
// java.lang.Class<TDocument>) // java.lang.Class<TDocument>)
// noinspection unchecked // noinspection unchecked
JsonEndpoint<GetRequest, GetResponse<T>, ErrorResponse> endpoint = (JsonEndpoint<GetRequest, GetResponse<T>, ErrorResponse>) GetRequest._ENDPOINT; JsonEndpoint<GetRequest, GetResponse<T>, ErrorResponse> endpoint = (JsonEndpoint<GetRequest, GetResponse<T>, ErrorResponse>) GetRequest._ENDPOINT;
endpoint = new EndpointWithResponseMapperAttr<>(endpoint, "co.elastic.clients:Deserializer:_global.get.TDocument", endpoint = new EndpointWithResponseMapperAttr<>(endpoint, "co.elastic.clients:Deserializer:_global.get.Response.TDocument",
getDeserializer(tClass)); getDeserializer(tClass));
return Mono.fromFuture(transport.performRequestAsync(request, endpoint, transportOptions)); return Mono.fromFuture(transport.performRequestAsync(request, endpoint, transportOptions));
@ -145,7 +145,7 @@ public class ReactiveElasticsearchClient extends ApiClient<ElasticsearchTranspor
// noinspection unchecked // noinspection unchecked
JsonEndpoint<UpdateRequest<?, ?>, UpdateResponse<T>, ErrorResponse> endpoint = new EndpointWithResponseMapperAttr( JsonEndpoint<UpdateRequest<?, ?>, UpdateResponse<T>, ErrorResponse> endpoint = new EndpointWithResponseMapperAttr(
UpdateRequest._ENDPOINT, "co.elastic.clients:Deserializer:_global.update.TDocument", UpdateRequest._ENDPOINT, "co.elastic.clients:Deserializer:_global.update.Response.TDocument",
this.getDeserializer(clazz)); this.getDeserializer(clazz));
return Mono.fromFuture(transport.performRequestAsync(request, endpoint, this.transportOptions)); return Mono.fromFuture(transport.performRequestAsync(request, endpoint, this.transportOptions));
} }
@ -171,7 +171,7 @@ public class ReactiveElasticsearchClient extends ApiClient<ElasticsearchTranspor
// noinspection unchecked // noinspection unchecked
JsonEndpoint<MgetRequest, MgetResponse<T>, ErrorResponse> endpoint = (JsonEndpoint<MgetRequest, MgetResponse<T>, ErrorResponse>) MgetRequest._ENDPOINT; JsonEndpoint<MgetRequest, MgetResponse<T>, ErrorResponse> endpoint = (JsonEndpoint<MgetRequest, MgetResponse<T>, ErrorResponse>) MgetRequest._ENDPOINT;
endpoint = new EndpointWithResponseMapperAttr<>(endpoint, "co.elastic.clients:Deserializer:_global.mget.TDocument", endpoint = new EndpointWithResponseMapperAttr<>(endpoint, "co.elastic.clients:Deserializer:_global.mget.Response.TDocument",
this.getDeserializer(clazz)); this.getDeserializer(clazz));
return Mono.fromFuture(transport.performRequestAsync(request, endpoint, transportOptions)); return Mono.fromFuture(transport.performRequestAsync(request, endpoint, transportOptions));
@ -282,7 +282,7 @@ public class ReactiveElasticsearchClient extends ApiClient<ElasticsearchTranspor
// noinspection unchecked // noinspection unchecked
JsonEndpoint<ScrollRequest, ScrollResponse<T>, ErrorResponse> endpoint = (JsonEndpoint<ScrollRequest, ScrollResponse<T>, ErrorResponse>) ScrollRequest._ENDPOINT; JsonEndpoint<ScrollRequest, ScrollResponse<T>, ErrorResponse> endpoint = (JsonEndpoint<ScrollRequest, ScrollResponse<T>, ErrorResponse>) ScrollRequest._ENDPOINT;
endpoint = new EndpointWithResponseMapperAttr<>(endpoint, endpoint = new EndpointWithResponseMapperAttr<>(endpoint,
"co.elastic.clients:Deserializer:_global.scroll.TDocument", getDeserializer(tDocumentClass)); "co.elastic.clients:Deserializer:_global.scroll.Response.TDocument", getDeserializer(tDocumentClass));
return Mono.fromFuture(transport.performRequestAsync(request, endpoint, transportOptions)); return Mono.fromFuture(transport.performRequestAsync(request, endpoint, transportOptions));
} }

View File

@ -20,7 +20,6 @@ import static org.springframework.util.CollectionUtils.*;
import co.elastic.clients.elasticsearch._types.Conflicts; import co.elastic.clients.elasticsearch._types.Conflicts;
import co.elastic.clients.elasticsearch._types.ExpandWildcard; import co.elastic.clients.elasticsearch._types.ExpandWildcard;
import co.elastic.clients.elasticsearch._types.InlineScript;
import co.elastic.clients.elasticsearch._types.NestedSortValue; import co.elastic.clients.elasticsearch._types.NestedSortValue;
import co.elastic.clients.elasticsearch._types.OpType; import co.elastic.clients.elasticsearch._types.OpType;
import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.SortOptions;
@ -744,16 +743,12 @@ class RequestConverter extends AbstractQueryProcessor {
scriptData.params().forEach((key, value) -> params.put(key, JsonData.of(value, jsonpMapper))); scriptData.params().forEach((key, value) -> params.put(key, JsonData.of(value, jsonpMapper)));
} }
return co.elastic.clients.elasticsearch._types.Script.of(sb -> { return co.elastic.clients.elasticsearch._types.Script.of(sb -> {
sb.lang(scriptData.language())
.params(params);
if (scriptData.type() == ScriptType.INLINE) { if (scriptData.type() == ScriptType.INLINE) {
sb.inline(is -> is // sb.source(scriptData.script());
.lang(scriptData.language()) //
.source(scriptData.script()) //
.params(params)); //
} else if (scriptData.type() == ScriptType.STORED) { } else if (scriptData.type() == ScriptType.STORED) {
sb.stored(ss -> ss // sb.id(scriptData.script());
.id(scriptData.script()) //
.params(params) //
);
} }
return sb; return sb;
}); });
@ -925,7 +920,9 @@ class RequestConverter extends AbstractQueryProcessor {
ReindexRequest.Script script = reindexRequest.getScript(); ReindexRequest.Script script = reindexRequest.getScript();
if (script != null) { if (script != null) {
builder.script(s -> s.inline(InlineScript.of(i -> i.lang(script.getLang()).source(script.getSource())))); builder.script(sb -> sb
.lang(script.getLang())
.source(script.getSource()));
} }
builder.timeout(time(reindexRequest.getTimeout())) // builder.timeout(time(reindexRequest.getTimeout())) //
@ -1078,21 +1075,15 @@ class RequestConverter extends AbstractQueryProcessor {
} }
uqb.script(sb -> { uqb.script(sb -> {
sb.lang(query.getLang()).params(params);
if (query.getScriptType() == ScriptType.INLINE) { if (query.getScriptType() == ScriptType.INLINE) {
sb.inline(is -> is // sb.source(query.getScript()); //
.lang(query.getLang()) //
.source(query.getScript()) //
.params(params)); //
} else if (query.getScriptType() == ScriptType.STORED) { } else if (query.getScriptType() == ScriptType.STORED) {
sb.stored(ss -> ss // sb.id(query.getScript());
.id(query.getScript()) //
.params(params) //
);
} }
return sb; return sb;
} });
);
} }
uqb // uqb //
@ -1347,17 +1338,16 @@ class RequestConverter extends AbstractQueryProcessor {
String script = runtimeField.getScript(); String script = runtimeField.getScript();
if (script != null) { if (script != null) {
rfb rfb.script(s -> {
.script(s -> s s.source(script);
.inline(is -> {
is.source(script);
if (runtimeField.getParams() != null) { if (runtimeField.getParams() != null) {
is.params(TypeUtils.paramsMap(runtimeField.getParams())); s.params(TypeUtils.paramsMap(runtimeField.getParams()));
} }
return is; return s;
})); });
} }
return rfb; return rfb;
}); });
runtimeMappings.put(runtimeField.getName(), esRuntimeField); runtimeMappings.put(runtimeField.getName(), esRuntimeField);
@ -1548,16 +1538,14 @@ class RequestConverter extends AbstractQueryProcessor {
rfb.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType())); rfb.type(RuntimeFieldType._DESERIALIZER.parse(runtimeField.getType()));
String script = runtimeField.getScript(); String script = runtimeField.getScript();
if (script != null) { if (script != null) {
rfb rfb.script(s -> {
.script(s -> s s.source(script);
.inline(is -> {
is.source(script);
if (runtimeField.getParams() != null) { if (runtimeField.getParams() != null) {
is.params(TypeUtils.paramsMap(runtimeField.getParams())); s.params(TypeUtils.paramsMap(runtimeField.getParams()));
} }
return is; return s;
})); });
} }
return rfb; return rfb;

View File

@ -34,12 +34,12 @@ public class IndexCoordinates {
private final String[] indexNames; private final String[] indexNames;
public static IndexCoordinates of(String... indexNames) { public static IndexCoordinates of(String... indexNames) {
Assert.notNull(indexNames, "indexNames must not be null");
return new IndexCoordinates(indexNames); return new IndexCoordinates(indexNames);
} }
private IndexCoordinates(String... indexNames) { private IndexCoordinates(String... indexNames) {
Assert.notEmpty(indexNames, "indexNames may not be null or empty"); Assert.notEmpty(indexNames, "indexNames may not be null or empty");
Assert.noNullElements(indexNames, "indexNames may not contain null elements");
this.indexNames = indexNames; this.indexNames = indexNames;
} }

View File

@ -190,44 +190,42 @@ public class ElasticsearchELCIntegrationTests extends ElasticsearchIntegrationTe
@Override @Override
protected Query getQueryWithRescorer() { protected Query getQueryWithRescorer() {
return NativeQuery.builder() // return NativeQuery.builder()
.withQuery(q -> q // .withQuery(q -> q
.bool(b -> b // .bool(b -> b
.filter(f -> f.exists(e -> e.field("rate"))) // .filter(f -> f.exists(e -> e.field("rate")))
.should(s -> s.term(t -> t.field("message").value("message"))) // .should(s -> s.term(t -> t.field("message").value("message")))))
)) // .withRescorerQuery(
.withRescorerQuery( // new RescorerQuery(NativeQuery.builder()
new RescorerQuery(NativeQuery.builder() // .withQuery(q -> q
.withQuery(q -> q // .functionScore(fs -> fs
.functionScore(fs -> fs // .functions(f1 -> f1
.functions(f1 -> f1 // .filter(matchAllQueryAsQuery())
.filter(matchAllQueryAsQuery()) // .weight(1.0)
.weight(1.0) // .gauss(d -> d
.gauss(d -> d // .untyped(ut -> ut
.field("rate") // .field("rate")
.placement(dp -> dp // .placement(dp -> dp
.origin(JsonData.of(0)) // .origin(JsonData.of(0))
.scale(JsonData.of(10)) // .scale(JsonData.of(10))
.decay(0.5)) // .decay(0.5)))))
)) // .functions(f2 -> f2
.functions(f2 -> f2 // .filter(matchAllQueryAsQuery()).weight(100.0)
.filter(matchAllQueryAsQuery()).weight(100.0) // .gauss(d -> d
.gauss(d -> d // .untyped(ut -> ut
.field("rate") // .field("rate")
.placement(dp -> dp // .placement(dp -> dp
.origin(JsonData.of(0)) // .origin(JsonData.of(0))
.scale(JsonData.of(10)) // .scale(JsonData.of(10))
.decay(0.5)) // .decay(0.5)))
)) // ))
.scoreMode(FunctionScoreMode.Sum) // .scoreMode(FunctionScoreMode.Sum)
.maxBoost(80.0) // .maxBoost(80.0)
.boostMode(FunctionBoostMode.Replace)) // .boostMode(FunctionBoostMode.Replace)))
) // .build())
.build() // .withScoreMode(RescorerQuery.ScoreMode.Max)
) // .withWindowSize(100))
.withScoreMode(RescorerQuery.ScoreMode.Max) //
.withWindowSize(100)) //
.build(); .build();
} }
} }

View File

@ -23,11 +23,12 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
/** /**
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
*/ */
@SuppressWarnings("DataFlowIssue")
class IndexCoordinatesUnitTests { class IndexCoordinatesUnitTests {
@Test @Test
void cannotBeInitializedWithNullIndexName() { void cannotBeInitializedWithNullIndexName() {
assertThatThrownBy(() -> IndexCoordinates.of(null)).isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> IndexCoordinates.of((String) null)).isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test

View File

@ -54,12 +54,13 @@ public class LogEntityELCIntegrationTests extends LogEntityIntegrationTests {
@Override @Override
Query rangeQueryForIp(String from, String to) { Query rangeQueryForIp(String from, String to) {
return NativeQuery.builder() // return NativeQuery.builder()
.withQuery(qb -> qb // .withQuery(qb -> qb
.range(rqb -> rqb // .range(rqb -> rqb
.field("ip") // .untyped(ut -> ut
.gte(JsonData.of(from))// .field("ip")
.lte(JsonData.of(to))// .gte(JsonData.of(from))
)).build(); .lte(JsonData.of(to)))))
.build();
} }
} }

View File

@ -15,7 +15,7 @@
# #
# #
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
sde.testcontainers.image-version=8.14.3 sde.testcontainers.image-version=8.15.0
# #
# #
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13 # needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13