es java client major update.

Original Pull Request #3116
Closes #3110
Signed-off-by: Laura Trotta <laura.trotta@elastic.co>
This commit is contained in:
Laura Trotta 2025-05-29 15:56:35 +02:00 committed by GitHub
parent 6268133506
commit 158f5fc342
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 68 additions and 131 deletions

View File

@ -21,7 +21,7 @@
<springdata.commons>4.0.0-SNAPSHOT</springdata.commons>
<!-- version of the ElasticsearchClient -->
<elasticsearch-java>8.18.1</elasticsearch-java>
<elasticsearch-java>9.0.1</elasticsearch-java>
<hoverfly>0.19.0</hoverfly>
<log4j>2.23.1</log4j>

View File

@ -83,7 +83,7 @@ final class DocumentAdapters {
Explanation explanation = from(hit.explanation());
List<String> matchedQueries = hit.matchedQueries();
Map<String, Double> matchedQueries = hit.matchedQueries();
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
StringBuilder sb = new StringBuilder("{");

View File

@ -539,14 +539,6 @@ public class ReactiveElasticsearchIndicesClient
return stats(builder -> builder);
}
public Mono<UnfreezeResponse> unfreeze(UnfreezeRequest request) {
return Mono.fromFuture(transport.performRequestAsync(request, UnfreezeRequest._ENDPOINT, transportOptions));
}
public Mono<UnfreezeResponse> unfreeze(Function<UnfreezeRequest.Builder, ObjectBuilder<UnfreezeRequest>> fn) {
return unfreeze(fn.apply(new UnfreezeRequest.Builder()).build());
}
public Mono<UpdateAliasesResponse> updateAliases(UpdateAliasesRequest request) {
return Mono.fromFuture(transport.performRequestAsync(request, UpdateAliasesRequest._ENDPOINT, transportOptions));
}

View File

@ -42,10 +42,10 @@ import co.elastic.clients.elasticsearch.core.bulk.CreateOperation;
import co.elastic.clients.elasticsearch.core.bulk.IndexOperation;
import co.elastic.clients.elasticsearch.core.bulk.UpdateOperation;
import co.elastic.clients.elasticsearch.core.mget.MultiGetOperation;
import co.elastic.clients.elasticsearch.core.msearch.MultisearchBody;
import co.elastic.clients.elasticsearch.core.msearch.MultisearchHeader;
import co.elastic.clients.elasticsearch.core.search.Highlight;
import co.elastic.clients.elasticsearch.core.search.Rescore;
import co.elastic.clients.elasticsearch.core.search.SearchRequestBody;
import co.elastic.clients.elasticsearch.core.search.SourceConfig;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.elasticsearch.indices.ExistsIndexTemplateRequest;
@ -751,11 +751,10 @@ class RequestConverter extends AbstractQueryProcessor {
}
return co.elastic.clients.elasticsearch._types.Script.of(sb -> {
sb.lang(scriptData.language())
.params(params);
if (scriptData.type() == ScriptType.INLINE) {
sb.source(scriptData.script());
} else if (scriptData.type() == ScriptType.STORED) {
sb.id(scriptData.script());
.params(params)
.id(scriptData.scriptName());
if (scriptData.script() != null){
sb.source(s -> s.scriptString(scriptData.script()));
}
return sb;
});
@ -927,9 +926,13 @@ class RequestConverter extends AbstractQueryProcessor {
ReindexRequest.Script script = reindexRequest.getScript();
if (script != null) {
builder.script(sb -> sb
.lang(script.getLang())
.source(script.getSource()));
builder.script(sb -> {
if (script.getSource() != null){
sb.source(s -> s.scriptString(script.getSource()));
}
sb.lang(script.getLang());
return sb;
});
}
builder.timeout(time(reindexRequest.getTimeout())) //
@ -1086,12 +1089,11 @@ class RequestConverter extends AbstractQueryProcessor {
uqb.script(sb -> {
sb.lang(query.getLang()).params(params);
if (query.getScriptType() == ScriptType.INLINE) {
sb.source(query.getScript()); //
} else if (query.getScriptType() == ScriptType.STORED) {
sb.id(query.getScript());
if (query.getScript() != null){
sb.source(s -> s.scriptString(query.getScript()));
}
sb.id(query.getId());
return sb;
});
}
@ -1254,11 +1256,11 @@ class RequestConverter extends AbstractQueryProcessor {
mtrb.searchTemplates(stb -> stb
.header(msearchHeaderBuilder(query, param.index(), routing))
.body(bb -> {
bb //
.explain(query.getExplain()) //
.id(query.getId()) //
.source(query.getSource()) //
;
bb.explain(query.getExplain()) //
.id(query.getId()); //
if (query.getSource() != null){
bb.source(s -> s.scriptString(query.getSource()));
}
if (!CollectionUtils.isEmpty(query.getParams())) {
Map<String, JsonData> params = getTemplateParams(query.getParams().entrySet());
@ -1349,7 +1351,9 @@ class RequestConverter extends AbstractQueryProcessor {
if (script != null) {
rfb.script(s -> {
s.source(script);
if (script != null) {
s.source(so -> so.scriptString(script));
}
if (runtimeField.getParams() != null) {
s.params(TypeUtils.paramsMap(runtimeField.getParams()));
@ -1551,7 +1555,9 @@ class RequestConverter extends AbstractQueryProcessor {
String script = runtimeField.getScript();
if (script != null) {
rfb.script(s -> {
s.source(script);
if (script != null) {
s.source(so -> so.scriptString(script));
}
if (runtimeField.getParams() != null) {
s.params(TypeUtils.paramsMap(runtimeField.getParams()));
@ -1648,7 +1654,7 @@ class RequestConverter extends AbstractQueryProcessor {
builder.highlight(highlight);
}
private void addHighlight(Query query, MultisearchBody.Builder builder) {
private void addHighlight(Query query, SearchRequestBody.Builder builder) {
Highlight highlight = query.getHighlightQuery()
.map(highlightQuery -> new HighlightQueryBuilder(elasticsearchConverter.getMappingContext(), this)
@ -1772,7 +1778,7 @@ class RequestConverter extends AbstractQueryProcessor {
}
@SuppressWarnings("DuplicatedCode")
private void prepareNativeSearch(NativeQuery query, MultisearchBody.Builder builder) {
private void prepareNativeSearch(NativeQuery query, SearchRequestBody.Builder builder) {
builder //
.suggest(query.getSuggester()) //
@ -1891,10 +1897,11 @@ class RequestConverter extends AbstractQueryProcessor {
.id(query.getId()) //
.index(Arrays.asList(index.getIndexNames())) //
.preference(query.getPreference()) //
.searchType(searchType(query.getSearchType())) //
.source(query.getSource()) //
;
.searchType(searchType(query.getSearchType())); //
if (query.getSource() != null) {
builder.source(so -> so.scriptString(query.getSource()));
}
if (query.getRoute() != null) {
builder.routing(query.getRoute());
} else if (StringUtils.hasText(routing)) {
@ -1937,7 +1944,7 @@ class RequestConverter extends AbstractQueryProcessor {
.id(script.id()) //
.script(sb -> sb //
.lang(script.language()) //
.source(script.source())));
.source(s -> s.scriptString(script.source()))));
}
public GetScriptRequest scriptGet(String name) {

View File

@ -191,7 +191,7 @@ class ResponseConverter {
Assert.notNull(getMappingResponse, "getMappingResponse must not be null");
Assert.notNull(indexCoordinates, "indexCoordinates must not be null");
Map<String, IndexMappingRecord> mappings = getMappingResponse.result();
Map<String, IndexMappingRecord> mappings = getMappingResponse.mappings();
if (mappings == null || mappings.isEmpty()) {
return Document.create();
@ -219,7 +219,7 @@ class ResponseConverter {
List<IndexInformation> indexInformationList = new ArrayList<>();
getIndexResponse.result().forEach((indexName, indexState) -> {
getIndexResponse.indices().forEach((indexName, indexState) -> {
Settings settings = indexState.settings() != null ? Settings.parse(toJson(indexState.settings(), jsonpMapper))
: new Settings();
Document mappings = indexState.mappings() != null ? Document.parse(toJson(indexState.mappings(), jsonpMapper))
@ -239,7 +239,7 @@ class ResponseConverter {
Assert.notNull(getAliasResponse, "getAliasResponse must not be null");
Map<String, Set<AliasData>> aliasDataMap = new HashMap<>();
getAliasResponse.result().forEach((indexName, alias) -> {
getAliasResponse.aliases().forEach((indexName, alias) -> {
Set<AliasData> aliasDataSet = new HashSet<>();
alias.aliases()
.forEach((aliasName, aliasDefinition) -> aliasDataSet.add(indicesGetAliasData(aliasName, aliasDefinition)));
@ -535,7 +535,7 @@ class ResponseConverter {
? Script.builder() //
.withId(response.id()) //
.withLanguage(response.script().lang()) //
.withSource(response.script().source()).build() //
.withSource(response.script().source().scriptString()).build() //
: null;
}
// endregion

View File

@ -48,12 +48,12 @@ public class SearchHit<T> {
@Nullable private final NestedMetaData nestedMetaData;
@Nullable private final String routing;
@Nullable private final Explanation explanation;
private final List<String> matchedQueries = new ArrayList<>();
private final Map<String, Double> matchedQueries = new LinkedHashMap<>();
public SearchHit(@Nullable String index, @Nullable String id, @Nullable String routing, float score,
@Nullable Object[] sortValues, @Nullable Map<String, List<String>> highlightFields,
@Nullable Map<String, SearchHits<?>> innerHits, @Nullable NestedMetaData nestedMetaData,
@Nullable Explanation explanation, @Nullable List<String> matchedQueries, T content) {
@Nullable Explanation explanation, @Nullable Map<String, Double> matchedQueries, T content) {
this.index = index;
this.id = id;
this.routing = routing;
@ -73,7 +73,7 @@ public class SearchHit<T> {
this.content = content;
if (matchedQueries != null) {
this.matchedQueries.addAll(matchedQueries);
this.matchedQueries.putAll(matchedQueries);
}
}
@ -194,7 +194,7 @@ public class SearchHit<T> {
* @return the matched queries for this SearchHit.
*/
@Nullable
public List<String> getMatchedQueries() {
public Map<String, Double> getMatchedQueries() {
return matchedQueries;
}
}

View File

@ -125,5 +125,5 @@ public interface SearchDocument extends Document {
* @return the matched queries for the SearchHit.
*/
@Nullable
List<String> getMatchedQueries();
Map<String, Double> getMatchedQueries();
}

View File

@ -41,12 +41,12 @@ public class SearchDocumentAdapter implements SearchDocument {
private final Map<String, SearchDocumentResponse> innerHits = new HashMap<>();
@Nullable private final NestedMetaData nestedMetaData;
@Nullable private final Explanation explanation;
@Nullable private final List<String> matchedQueries;
@Nullable private final Map<String, Double> matchedQueries;
@Nullable private final String routing;
public SearchDocumentAdapter(Document delegate, float score, Object[] sortValues, Map<String, List<Object>> fields,
Map<String, List<String>> highlightFields, Map<String, SearchDocumentResponse> innerHits,
@Nullable NestedMetaData nestedMetaData, @Nullable Explanation explanation, @Nullable List<String> matchedQueries,
@Nullable NestedMetaData nestedMetaData, @Nullable Explanation explanation, @Nullable Map<String, Double> matchedQueries,
@Nullable String routing) {
this.delegate = delegate;
@ -249,7 +249,7 @@ public class SearchDocumentAdapter implements SearchDocument {
@Override
@Nullable
public List<String> getMatchedQueries() {
public Map<String, Double> getMatchedQueries() {
return matchedQueries;
}

View File

@ -27,15 +27,12 @@ import org.springframework.util.Assert;
* @author Peter-Josef Meisch
* @since 4.4
*/
public record ScriptData(ScriptType type, @Nullable String language, @Nullable String script,
public record ScriptData(@Nullable String language, @Nullable String script,
@Nullable String scriptName, @Nullable Map<String, Object> params) {
public ScriptData(ScriptType type, @Nullable String language, @Nullable String script, @Nullable String scriptName,
public ScriptData(@Nullable String language, @Nullable String script, @Nullable String scriptName,
@Nullable Map<String, Object> params) {
Assert.notNull(type, "type must not be null");
this.type = type;
this.language = language;
this.script = script;
this.scriptName = scriptName;
@ -45,9 +42,9 @@ public record ScriptData(ScriptType type, @Nullable String language, @Nullable S
/**
* @since 5.2
*/
public static ScriptData of(ScriptType type, @Nullable String language, @Nullable String script,
public static ScriptData of(@Nullable String language, @Nullable String script,
@Nullable String scriptName, @Nullable Map<String, Object> params) {
return new ScriptData(type, language, script, scriptName, params);
return new ScriptData(language, script, scriptName, params);
}
public static ScriptData of(Function<Builder, Builder> builderFunction) {
@ -68,7 +65,6 @@ public record ScriptData(ScriptType type, @Nullable String language, @Nullable S
* @since 5.2
*/
public static final class Builder {
@Nullable private ScriptType type;
@Nullable private String language;
@Nullable private String script;
@Nullable private String scriptName;
@ -76,14 +72,6 @@ public record ScriptData(ScriptType type, @Nullable String language, @Nullable S
private Builder() {}
public Builder withType(ScriptType type) {
Assert.notNull(type, "type must not be null");
this.type = type;
return this;
}
public Builder withLanguage(@Nullable String language) {
this.language = language;
return this;
@ -106,9 +94,7 @@ public record ScriptData(ScriptType type, @Nullable String language, @Nullable S
public ScriptData build() {
Assert.notNull(type, "type must be set");
return new ScriptData(type, language, script, scriptName, params);
return new ScriptData(language, script, scriptName, params);
}
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright 2021-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.query;
/**
* Define script types for update queries.
*
* @author Farid Faoudi
* @since 4.2
*/
public enum ScriptType {
INLINE, STORED
}

View File

@ -76,7 +76,7 @@ public class UpdateQuery {
@Nullable String timeout, @Nullable String waitForActiveShards, @Nullable Query query,
@Nullable Boolean abortOnVersionConflict, @Nullable Integer batchSize, @Nullable Integer maxDocs,
@Nullable Integer maxRetries, @Nullable String pipeline, @Nullable Float requestsPerSecond,
@Nullable Boolean shouldStoreResult, @Nullable Integer slices, @Nullable ScriptType scriptType,
@Nullable Boolean shouldStoreResult, @Nullable Integer slices,
@Nullable String scriptName, @Nullable String indexName) {
this.id = id;
@ -105,8 +105,8 @@ public class UpdateQuery {
this.slices = slices;
this.indexName = indexName;
if (scriptType != null || lang != null || script != null || scriptName != null || params != null) {
this.scriptData = new ScriptData(scriptType, lang, script, scriptName, params);
if (lang != null || script != null || scriptName != null || params != null) {
this.scriptData = new ScriptData(lang, script, scriptName, params);
} else {
this.scriptData = null;
}
@ -246,11 +246,6 @@ public class UpdateQuery {
return slices;
}
@Nullable
public ScriptType getScriptType() {
return scriptData != null ? scriptData.type() : null;
}
@Nullable
public String getScriptName() {
return scriptData != null ? scriptData.scriptName() : null;
@ -300,7 +295,6 @@ public class UpdateQuery {
@Nullable private Float requestsPerSecond;
@Nullable private Boolean shouldStoreResult;
@Nullable private Integer slices;
@Nullable private ScriptType scriptType;
@Nullable private String scriptName;
@Nullable private String indexName;
@ -437,11 +431,6 @@ public class UpdateQuery {
return this;
}
public Builder withScriptType(ScriptType scriptType) {
this.scriptType = scriptType;
return this;
}
public Builder withScriptName(String scriptName) {
this.scriptName = scriptName;
return this;
@ -456,7 +445,7 @@ public class UpdateQuery {
return new UpdateQuery(id, script, params, document, upsert, lang, routing, scriptedUpsert, docAsUpsert,
fetchSource, fetchSourceIncludes, fetchSourceExcludes, ifSeqNo, ifPrimaryTerm, refreshPolicy, retryOnConflict,
timeout, waitForActiveShards, query, abortOnVersionConflict, batchSize, maxDocs, maxRetries, pipeline,
requestsPerSecond, shouldStoreResult, slices, scriptType, scriptName, indexName);
requestsPerSecond, shouldStoreResult, slices, scriptName, indexName);
}
public Builder withIndex(@Nullable String indexName) {

View File

@ -249,16 +249,15 @@ public class ReindexRequest {
}
public static class Script {
private final String source;
@Nullable private final String source;
@Nullable private final String lang;
private Script(String source, @Nullable String lang) {
Assert.notNull(source, "source must not be null");
private Script(@Nullable String source, @Nullable String lang) {
this.source = source;
this.lang = lang;
}
@Nullable
public String getSource() {
return source;
}

View File

@ -28,8 +28,6 @@ public record Script(String id, String language, String source) {
Assert.notNull(id, "id must not be null");
Assert.notNull(language, "language must not be null");
Assert.notNull(source, "source must not be null");
}
public static ScriptBuilder builder() {
@ -62,8 +60,6 @@ public record Script(String id, String language, String source) {
public ScriptBuilder withSource(String source) {
Assert.notNull(source, "source must not be null");
this.source = source;
return this;
}

View File

@ -23,6 +23,7 @@ import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.assertj.core.api.SoftAssertions;
import org.assertj.core.data.Offset;
@ -144,17 +145,17 @@ class DocumentAdaptersUnitTests {
Hit<EntityAsMap> searchHit = new Hit.Builder<EntityAsMap>() //
.index("index") //
.id("42") //
.matchedQueries("query1", "query2") //
.matchedQueries("query1", 1D) //
.build();
SearchDocument searchDocument = DocumentAdapters.from(searchHit, jsonpMapper);
SoftAssertions softly = new SoftAssertions();
List<String> matchedQueries = searchDocument.getMatchedQueries();
Map<String, Double> matchedQueries = searchDocument.getMatchedQueries();
softly.assertThat(matchedQueries).isNotNull();
softly.assertThat(matchedQueries).hasSize(2);
softly.assertThat(matchedQueries).isEqualTo(Arrays.asList("query1", "query2"));
softly.assertThat(matchedQueries).hasSize(1);
softly.assertThat(matchedQueries).isEqualTo(Map.of("query1",1D));
softly.assertAll();
}
}

View File

@ -46,7 +46,6 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
import org.springframework.data.elasticsearch.core.query.ScriptData;
import org.springframework.data.elasticsearch.core.query.ScriptType;
import org.springframework.data.elasticsearch.core.query.ScriptedField;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
@ -183,7 +182,7 @@ public class ElasticsearchELCIntegrationTests extends ElasticsearchIntegrationTe
return nativeQueryBuilder.withScriptedField(new ScriptedField( //
fieldName, //
new ScriptData(ScriptType.INLINE, "expression", script, null, params))) //
new ScriptData( "expression", script, null, params))) //
.build();
}

View File

@ -1630,7 +1630,6 @@ public abstract class ElasticsearchIntegrationTests {
final Query query = operations.matchAllQuery();
final UpdateQuery updateQuery = UpdateQuery.builder(query)
.withScriptType(ScriptType.INLINE)
.withScript("ctx._source['message'] = params['newMessage']").withLang("painless")
.withParams(Collections.singletonMap("newMessage", messageAfterUpdate)).withAbortOnVersionConflict(true)
.build();

View File

@ -48,7 +48,6 @@ import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilde
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RuntimeField;
import org.springframework.data.elasticsearch.core.query.ScriptData;
import org.springframework.data.elasticsearch.core.query.ScriptType;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
@ -165,7 +164,6 @@ public abstract class ReactiveScriptedAndRuntimeFieldsIntegrationTests {
return org.springframework.data.elasticsearch.core.query.ScriptedField.of(
fieldName,
ScriptData.of(b -> b
.withType(ScriptType.INLINE)
.withScript("doc['value'].size() > 0 ? doc['value'].value * params['factor'] : 0")
.withParams(Map.of("factor", factor))));
}

View File

@ -45,7 +45,6 @@ import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilde
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RuntimeField;
import org.springframework.data.elasticsearch.core.query.ScriptData;
import org.springframework.data.elasticsearch.core.query.ScriptType;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
@ -314,7 +313,6 @@ public abstract class ScriptedAndRuntimeFieldsIntegrationTests {
return org.springframework.data.elasticsearch.core.query.ScriptedField.of(
fieldName,
ScriptData.of(b -> b
.withType(ScriptType.INLINE)
.withScript("doc['value'].size() > 0 ? doc['value'].value * params['factor'] : 0")
.withParams(Map.of("factor", factor))));
}

View File

@ -15,7 +15,7 @@
#
#
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
sde.testcontainers.image-version=8.18.1
sde.testcontainers.image-version=9.0.1
#
#
# 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