diff --git a/README.md b/README.md index c651e44..6cd917c 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ The Spring Data OpenSearch follows the release model of the Spring Data Elastics | Spring Data Release Train | Spring Data OpenSearch | Spring Data Elasticsearch | OpenSearch Server | OpenSearch Client | Spring Framework | Spring Boot | |---------------------------|------------------------|---------------------------|-------------------|-------------------|------------------|---------------| +| 2024.1 | 1.6.x | 5.4.x | 1.x / 2.x | 2.10.x and above | 6.2.x | 3.4.x | | 2024.0 | 1.5.x | 5.3.x | 1.x / 2.x | 2.10.x and above | 6.1.x | 3.2.x / 3.3.x | | 2023.1 (Vaughan) | 1.4.x | 5.2.x | 1.x / 2.x | 2.10.x and above | 6.1.x | 3.2.x | | 2023.1 (Vaughan) | 1.3.x | 5.2.x | 1.x / 2.x | 2.7.x and above | 6.1.x | 3.2.x | diff --git a/settings.gradle.kts b/settings.gradle.kts index 3dd07db..7217d9a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,16 +8,16 @@ rootProject.name = "spring-data-opensearch-parent" dependencyResolutionManagement { versionCatalogs { create("libs") { - version("jupiter", "5.11.2") + version("jupiter", "5.11.3") library("jupiter", "org.junit.jupiter", "junit-jupiter").versionRef("jupiter") library("jupiter-params", "org.junit.jupiter", "junit-jupiter-params").versionRef("jupiter") } create("springLibs") { - version("spring", "6.1.15") - version("spring-boot", "3.3.6") - library("data-commons", "org.springframework.data:spring-data-commons:3.3.6") - library("data-elasticsearch", "org.springframework.data:spring-data-elasticsearch:5.3.6") + version("spring", "6.2.0") + version("spring-boot", "3.4.0") + library("data-commons", "org.springframework.data:spring-data-commons:3.4.0") + library("data-elasticsearch", "org.springframework.data:spring-data-elasticsearch:5.4.0") library("web", "org.springframework", "spring-web").versionRef("spring") library("context", "org.springframework", "spring-context").versionRef("spring") library("tx", "org.springframework", "spring-tx").versionRef("spring") diff --git a/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/DocumentAdapters.java b/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/DocumentAdapters.java index 158ff21..7afb7f1 100644 --- a/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/DocumentAdapters.java +++ b/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/DocumentAdapters.java @@ -184,8 +184,8 @@ public static SearchDocument from(SearchHit source) { if (sourceInnerHits != null) { sourceInnerHits.forEach((name, searchHits) -> innerHits.put( name, - SearchDocumentResponseBuilder.from( - searchHits, null, null, null, null, searchDocument -> CompletableFuture.completedFuture(null)))); + SearchDocumentResponseBuilder.from(searchHits, null, null, 0, null, null, + searchDocument -> CompletableFuture.completedFuture(null)))); } NestedMetaData nestedMetaData = from(source.getNestedIdentity()); diff --git a/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/OpenSearchRestTemplate.java b/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/OpenSearchRestTemplate.java index 92a0297..bc562e2 100644 --- a/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/OpenSearchRestTemplate.java +++ b/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/OpenSearchRestTemplate.java @@ -71,10 +71,12 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.SqlQuery; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.core.query.UpdateResponse; import org.springframework.data.elasticsearch.core.reindex.ReindexRequest; import org.springframework.data.elasticsearch.core.reindex.ReindexResponse; +import org.springframework.data.elasticsearch.core.sql.SqlResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -631,6 +633,11 @@ protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest req return items; } + @Override + public SqlResponse search(SqlQuery query) { + throw new UnsupportedOperationException("The operation search(SqlQuery query) is not supported"); + } + // endregion // region ClientCallback diff --git a/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/SearchDocumentResponseBuilder.java b/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/SearchDocumentResponseBuilder.java index 79a2698..2376c89 100644 --- a/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/SearchDocumentResponseBuilder.java +++ b/spring-data-opensearch/src/main/java/org/opensearch/data/client/orhlc/SearchDocumentResponseBuilder.java @@ -9,6 +9,7 @@ package org.opensearch.data.client.orhlc; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -59,8 +60,10 @@ public static SearchDocumentResponse from( Aggregations aggregations = searchResponse.getAggregations(); org.opensearch.search.suggest.Suggest suggest = searchResponse.getSuggest(); SearchShardStatistics shardStatistics = shardsFrom(searchResponse); + var executionDurationInMillis = searchResponse.getTook().millis(); - return from(searchHits, shardStatistics, scrollId, aggregations, suggest, entityCreator); + return from(searchHits, shardStatistics, scrollId, executionDurationInMillis, + aggregations, suggest, entityCreator); } /** @@ -79,6 +82,7 @@ public static SearchDocumentResponse from( SearchHits searchHits, @Nullable SearchShardStatistics shardStatistics, @Nullable String scrollId, + long executionDurationInMillis, @Nullable Aggregations aggregations, @Nullable org.opensearch.search.suggest.Suggest suggestOS, SearchDocumentResponse.EntityCreator entityCreator) { @@ -97,6 +101,7 @@ public static SearchDocumentResponse from( } float maxScore = searchHits.getMaxScore(); + final Duration executionDuration = Duration.ofMillis(executionDurationInMillis); List searchDocuments = new ArrayList<>(); for (SearchHit searchHit : searchHits) { @@ -113,6 +118,7 @@ public static SearchDocumentResponse from( totalHits, totalHitsRelation, maxScore, + executionDuration, scrollId, null, searchDocuments, diff --git a/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/DocumentAdapters.java b/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/DocumentAdapters.java index fd319d6..3f2024e 100644 --- a/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/DocumentAdapters.java +++ b/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/DocumentAdapters.java @@ -73,7 +73,7 @@ public static SearchDocument from(Hit hit, JsonpMapper jsonpMapper) { Map innerHits = new LinkedHashMap<>(); hit.innerHits().forEach((name, innerHitsResult) -> { // noinspection ReturnOfNull - innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, null, null, + innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, 0, null, null, searchDocument -> null, jsonpMapper)); }); diff --git a/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/OpenSearchTemplate.java b/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/OpenSearchTemplate.java index ba071c3..823d95b 100644 --- a/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/OpenSearchTemplate.java +++ b/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/OpenSearchTemplate.java @@ -59,11 +59,13 @@ import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.SearchTemplateQuery; +import org.springframework.data.elasticsearch.core.query.SqlQuery; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.core.query.UpdateResponse; import org.springframework.data.elasticsearch.core.reindex.ReindexRequest; import org.springframework.data.elasticsearch.core.reindex.ReindexResponse; import org.springframework.data.elasticsearch.core.script.Script; +import org.springframework.data.elasticsearch.core.sql.SqlResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -642,6 +644,11 @@ public List listPointInTime() { .toList(); } + @Override + public SqlResponse search(SqlQuery query) { + throw new UnsupportedOperationException("The operation search(SqlQuery query) is not supported"); + } + // endregion // region script methods diff --git a/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilder.java b/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilder.java index 748048c..caee42f 100644 --- a/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilder.java +++ b/spring-data-opensearch/src/main/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilder.java @@ -15,6 +15,7 @@ */ package org.opensearch.data.client.osc; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -79,8 +80,9 @@ public static SearchDocumentResponse from(SearchResult response Map>> suggest = responseBody.suggest(); var pointInTimeId = responseBody.pitId(); var shards = responseBody.shards(); + var executionDurationInMillis = responseBody.took(); - return from(hitsMetadata, shards, scrollId, pointInTimeId, aggregations, suggest, entityCreator, jsonpMapper); + return from(hitsMetadata, shards, scrollId, pointInTimeId, executionDurationInMillis, aggregations, suggest, entityCreator, jsonpMapper); } /** @@ -105,8 +107,9 @@ public static SearchDocumentResponse from(SearchTemplateResponse SearchDocumentResponse from(SearchTemplateResponse SearchDocumentResponse from(HitsMetadata hitsMetadata, @Nullable ShardStatistics shards, - @Nullable String scrollId, @Nullable String pointInTimeId, @Nullable Map aggregations, + @Nullable String scrollId, @Nullable String pointInTimeId, long executionDurationInMillis, @Nullable Map aggregations, Map>> suggestES, SearchDocumentResponse.EntityCreator entityCreator, JsonpMapper jsonpMapper) { @@ -146,6 +149,7 @@ public static SearchDocumentResponse from(HitsMetadata hitsMetadata, @Nul } float maxScore = hitsMetadata.maxScore() != null ? hitsMetadata.maxScore().floatValue() : Float.NaN; + final Duration executionDuration = Duration.ofMillis(executionDurationInMillis); List searchDocuments = new ArrayList<>(); for (Hit hit : hitsMetadata.hits()) { @@ -159,8 +163,8 @@ public static SearchDocumentResponse from(HitsMetadata hitsMetadata, @Nul SearchShardStatistics shardStatistics = shards != null ? shardsFrom(shards) : null; - return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, pointInTimeId, searchDocuments, - aggregationsContainer, suggest, shardStatistics); + return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, executionDuration, + scrollId, pointInTimeId, searchDocuments, aggregationsContainer, suggest, shardStatistics); } private static SearchShardStatistics shardsFrom(ShardStatistics shards) { diff --git a/spring-data-opensearch/src/test/java/org/opensearch/data/client/core/OpenSearchRestTemplateCallbackTests.java b/spring-data-opensearch/src/test/java/org/opensearch/data/client/core/OpenSearchRestTemplateCallbackTests.java index 8df28e6..3ae99b7 100644 --- a/spring-data-opensearch/src/test/java/org/opensearch/data/client/core/OpenSearchRestTemplateCallbackTests.java +++ b/spring-data-opensearch/src/test/java/org/opensearch/data/client/core/OpenSearchRestTemplateCallbackTests.java @@ -34,6 +34,7 @@ import org.opensearch.action.search.SearchScrollRequest; import org.opensearch.client.RequestOptions; import org.opensearch.client.RestHighLevelClient; +import org.opensearch.common.unit.TimeValue; import org.opensearch.core.common.bytes.BytesArray; import org.opensearch.data.client.orhlc.OpenSearchRestTemplate; @@ -101,6 +102,7 @@ public void setUp() throws Exception { doReturn(searchResponse).when(client).search(any(SearchRequest.class), any(RequestOptions.class)); doReturn(nSearchHits(2)).when(searchResponse).getHits(); doReturn("scroll-id").when(searchResponse).getScrollId(); + doReturn(TimeValue.timeValueMillis(100)).when(searchResponse).getTook(); doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); doReturn(new HashMap() { { diff --git a/spring-data-opensearch/src/test/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilderUnitTests.java b/spring-data-opensearch/src/test/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilderUnitTests.java index 5af5f38..7e2f3fe 100644 --- a/spring-data-opensearch/src/test/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilderUnitTests.java +++ b/spring-data-opensearch/src/test/java/org/opensearch/data/client/osc/SearchDocumentResponseBuilderUnitTests.java @@ -78,7 +78,7 @@ void shouldGetPhraseSuggestion() throws JSONException { .build(); // act - final var actual = SearchDocumentResponseBuilder.from(hitsMetadata, null, null, null, null, sortProperties, null, + final var actual = SearchDocumentResponseBuilder.from(hitsMetadata, null, null, null, 0, null, sortProperties, null, jsonpMapper); // assert @@ -151,7 +151,7 @@ void shouldGetShardStatisticsInfo() { // act SearchDocumentResponse response = SearchDocumentResponseBuilder.from(hitsMetadata, shards, null, null, - null, null, null, jsonpMapper); + 0, null, null, null, jsonpMapper); // assert SearchShardStatistics shardStatistics = response.getSearchShardStatistics(); diff --git a/spring-data-opensearch/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java b/spring-data-opensearch/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java index 8804b46..698a419 100644 --- a/spring-data-opensearch/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java +++ b/spring-data-opensearch/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java @@ -37,6 +37,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.opensearch.data.client.EnabledIfOpenSearchVersion; import org.opensearch.data.client.junit.jupiter.OpenSearchRestTemplateConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -92,6 +93,13 @@ void setUp() { void cleanup() { operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*")).delete(); } + + @Test + @EnabledIfOpenSearchVersion(onOrAfter = "2.15.0", reason = "https://github.com/opensearch-project/OpenSearch/issues/5639") + public void shouldSupportAllTypes() { + IndexOperations indexOperations = operations.indexOps(EntityWithAllTypes.class); + indexOperations.createWithMapping(); + } @Test public void shouldNotFailOnCircularReference() { @@ -853,7 +861,7 @@ private static class EntityWithAllTypes { @Nullable @Field(type = FieldType.Percolator) String percolatorField; @Nullable - @Field(type = FieldType.Flattened) String flattenedField; + @Field(type = FieldType.Flattened, mappedTypeName = "flat_object") String flattenedField; @Nullable @Field(type = FieldType.Search_As_You_Type) String searchAsYouTypeField; @Nullable @@ -862,8 +870,6 @@ private static class EntityWithAllTypes { @Field(type = FieldType.Rank_Features) String rankFeaturesField; @Nullable @Field(type = FieldType.Wildcard) String wildcardField; - @Nullable - @Field(type = FieldType.Dense_Vector, dims = 1) String denseVectorField; } // endregion } diff --git a/version.properties b/version.properties index be05c9f..21d8ccd 100644 --- a/version.properties +++ b/version.properties @@ -1 +1 @@ -version=1.5.5 +version=1.6.0