Skip to content

Commit 64624ae

Browse files
authored
Encapsulate client specific aggregation return types.
Original Pull Request #1921 Closes #1920
1 parent e717586 commit 64624ae

17 files changed

+218
-48
lines changed

Diff for: src/main/asciidoc/reference/elasticsearch-migration-guide-4.2-4.3.adoc

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ Check the sections on <<elasticsearch-migration-guide-4.2-4.3.deprecations>> and
3030
* In the `org.springframework.data.elasticsearch.annotations.Document` annotation the `versionType()` property has changed to `org.springframework.data.elasticsearch.annotations.Document.VersionType`, the available enum values are the same.
3131
* In the `org.springframework.data.elasticsearch.core.query.Query` interface the `searchType()` property has changed to `org.springframework.data.elasticsearch.core.query.Query.SearchType`, the available enum values are the same.
3232
* In the `org.springframework.data.elasticsearch.core.query.Query` interface the return value of `timeout()` was changed to `java.time.Duration`.
33+
* The `SearchHits<T>`class does not contain the `org.elasticsearch.search.aggregations.Aggregations` anymore.
34+
Instead it now contains an instance of the `org.springframework.data.elasticsearch.core.AggregationsContainer<T>` class where `T` is the concrete aggregations type from the underlying client that is used.
35+
Currently this will be a `org
36+
.springframework.data.elasticsearch.core.clients.elasticsearch7.ElasticsearchAggregations` object; later different implementations will be available.
37+
The same change has been done to the `ReactiveSearchOperations.aggregate()` functions, the now return a `Flux<AggregationContainer<?>>`.
38+
Programs using the aggregations need to be changed to cast the returned value to the appropriate class to further proces it.
3339

3440
=== Handling of field and sourceFilter properties of Query
3541

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.core;
17+
18+
/**
19+
* Aggregation container used in the Spring Data Elasticsearch API for a single aggregation. The concrete
20+
* implementations must be provided by the code handling the direct communication with Elasticsearch.
21+
*
22+
* @author Peter-Josef Meisch
23+
* @param <T> the aggregation class from the used client implementation.
24+
* @since 4.3
25+
*/
26+
public interface AggregationContainer<T> {
27+
/**
28+
* @return the concrete aggregations implementation
29+
*/
30+
T aggregation();
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.core;
17+
18+
/**
19+
* Aggregations container used in the Spring Data Elasticsearch API. The concrete implementations must be provided by
20+
* the code handling the direct communication with Elasticsearch.
21+
*
22+
* @author Peter-Josef Meisch
23+
* @param <T> the aggregations class from the used client implementation.
24+
* @since 4.3
25+
*/
26+
public interface AggregationsContainer<T> {
27+
/**
28+
* @return the concrete aggregations implementation
29+
*/
30+
T aggregations();
31+
}

Diff for: src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.elasticsearch.index.reindex.BulkByScrollResponse;
4545
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
4646
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
47-
import org.elasticsearch.search.aggregations.Aggregation;
4847
import org.elasticsearch.search.suggest.Suggest;
4948
import org.elasticsearch.search.suggest.SuggestBuilder;
5049
import org.reactivestreams.Publisher;
@@ -59,6 +58,7 @@
5958
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
6059
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
6160
import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity;
61+
import org.springframework.data.elasticsearch.core.clients.elasticsearch7.ElasticsearchAggregation;
6262
import org.springframework.data.elasticsearch.core.cluster.DefaultReactiveClusterOperations;
6363
import org.springframework.data.elasticsearch.core.cluster.ReactiveClusterOperations;
6464
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@@ -782,12 +782,12 @@ private Mono<SearchDocumentResponse> doFindForResponse(Query query, Class<?> cla
782782
}
783783

784784
@Override
785-
public Flux<Aggregation> aggregate(Query query, Class<?> entityType) {
785+
public Flux<AggregationContainer<?>> aggregate(Query query, Class<?> entityType) {
786786
return aggregate(query, entityType, getIndexCoordinatesFor(entityType));
787787
}
788788

789789
@Override
790-
public Flux<Aggregation> aggregate(Query query, Class<?> entityType, IndexCoordinates index) {
790+
public Flux<AggregationContainer<?>> aggregate(Query query, Class<?> entityType, IndexCoordinates index) {
791791
return doAggregate(query, entityType, index);
792792
}
793793

@@ -808,7 +808,7 @@ private Flux<Suggest> doSuggest(SuggestBuilder suggestion, IndexCoordinates inde
808808
});
809809
}
810810

811-
private Flux<Aggregation> doAggregate(Query query, Class<?> entityType, IndexCoordinates index) {
811+
private Flux<AggregationContainer<?>> doAggregate(Query query, Class<?> entityType, IndexCoordinates index) {
812812
return Flux.defer(() -> {
813813
SearchRequest request = requestFactory.searchRequest(query, entityType, index);
814814
request = prepareSearchRequest(request, false);
@@ -872,14 +872,14 @@ protected Mono<SearchDocumentResponse> doFindForResponse(SearchRequest request)
872872
* @param request the already prepared {@link SearchRequest} ready to be executed.
873873
* @return a {@link Flux} emitting the result of the operation.
874874
*/
875-
protected Flux<Aggregation> doAggregate(SearchRequest request) {
875+
protected Flux<AggregationContainer<?>> doAggregate(SearchRequest request) {
876876

877877
if (QUERY_LOGGER.isDebugEnabled()) {
878878
QUERY_LOGGER.debug("Executing doCount: {}", request);
879879
}
880880

881881
return Flux.from(execute(client -> client.aggregate(request))) //
882-
.onErrorResume(NoSuchIndexException.class, it -> Flux.empty());
882+
.onErrorResume(NoSuchIndexException.class, it -> Flux.empty()).map(ElasticsearchAggregation::new);
883883
}
884884

885885
/**

Diff for: src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import java.util.List;
2222

23-
import org.elasticsearch.search.aggregations.Aggregation;
2423
import org.elasticsearch.search.suggest.Suggest;
2524
import org.elasticsearch.search.suggest.SuggestBuilder;
2625
import org.springframework.data.domain.Pageable;
@@ -185,7 +184,7 @@ default <T> Mono<SearchPage<T>> searchForPage(Query query, Class<T> entityType,
185184
* @return a {@link Flux} emitting matching aggregations one by one.
186185
* @since 4.0
187186
*/
188-
Flux<Aggregation> aggregate(Query query, Class<?> entityType);
187+
Flux<AggregationContainer<?>> aggregate(Query query, Class<?> entityType);
189188

190189
/**
191190
* Perform an aggregation specified by the given {@link Query query}. <br />
@@ -196,7 +195,7 @@ default <T> Mono<SearchPage<T>> searchForPage(Query query, Class<T> entityType,
196195
* @return a {@link Flux} emitting matching aggregations one by one.
197196
* @since 4.0
198197
*/
199-
Flux<Aggregation> aggregate(Query query, Class<?> entityType, IndexCoordinates index);
198+
Flux<AggregationContainer<?>> aggregate(Query query, Class<?> entityType, IndexCoordinates index);
200199

201200
/**
202201
* Does a suggest query

Diff for: src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Map;
2323
import java.util.stream.Collectors;
2424

25-
import org.elasticsearch.search.aggregations.Aggregations;
2625
import org.slf4j.Logger;
2726
import org.slf4j.LoggerFactory;
2827
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@@ -95,7 +94,7 @@ private SearchHitsImpl<T> mapHitsFromResponse(SearchDocumentResponse searchDocum
9594
SearchHit<T> hit = mapHit(document, content);
9695
searchHits.add(hit);
9796
}
98-
Aggregations aggregations = searchDocumentResponse.getAggregations();
97+
AggregationsContainer<?> aggregations = searchDocumentResponse.getAggregations();
9998
TotalHitsRelation totalHitsRelation = TotalHitsRelation.valueOf(searchDocumentResponse.getTotalHitsRelation());
10099

101100
return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations);
@@ -225,7 +224,7 @@ private SearchHits<?> mapInnerDocuments(SearchHits<SearchDocument> searchHits, C
225224

226225
/**
227226
* find a {@link ElasticsearchPersistentEntity} following the property chain defined by the nested metadata
228-
*
227+
*
229228
* @param persistentEntity base entity
230229
* @param nestedMetaData nested metadata
231230
* @return A {@link ElasticsearchPersistentEntityWithNestedMetaData} containing the found entity or null together with

Diff for: src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@
1818
import java.util.Iterator;
1919
import java.util.List;
2020

21-
import org.elasticsearch.search.aggregations.Aggregations;
2221
import org.springframework.data.util.Streamable;
2322
import org.springframework.lang.Nullable;
2423

2524
/**
2625
* Encapsulates a list of {@link SearchHit}s with additional information from the search.
27-
*
26+
*
2827
* @param <T> the result data class.
2928
* @author Sascha Woo
3029
* @since 4.0
@@ -35,7 +34,7 @@ public interface SearchHits<T> extends Streamable<SearchHit<T>> {
3534
* @return the aggregations.
3635
*/
3736
@Nullable
38-
Aggregations getAggregations();
37+
AggregationsContainer<?> getAggregations();
3938

4039
/**
4140
* @return the maximum score

Diff for: src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.Collections;
1919
import java.util.List;
2020

21-
import org.elasticsearch.search.aggregations.Aggregations;
2221
import org.springframework.data.util.Lazy;
2322
import org.springframework.lang.Nullable;
2423
import org.springframework.util.Assert;
@@ -39,7 +38,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
3938
@Nullable private final String scrollId;
4039
private final List<? extends SearchHit<T>> searchHits;
4140
private final Lazy<List<SearchHit<T>>> unmodifiableSearchHits;
42-
@Nullable private final Aggregations aggregations;
41+
@Nullable private final AggregationsContainer<?> aggregations;
4342

4443
/**
4544
* @param totalHits the number of total hits for the search
@@ -50,7 +49,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
5049
* @param aggregations the aggregations if available
5150
*/
5251
public SearchHitsImpl(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, @Nullable String scrollId,
53-
List<? extends SearchHit<T>> searchHits, @Nullable Aggregations aggregations) {
52+
List<? extends SearchHit<T>> searchHits, @Nullable AggregationsContainer<?> aggregations) {
5453

5554
Assert.notNull(searchHits, "searchHits must not be null");
5655

@@ -113,7 +112,7 @@ public String toString() {
113112
// region aggregations
114113
@Override
115114
@Nullable
116-
public Aggregations getAggregations() {
115+
public AggregationsContainer<?> getAggregations() {
117116
return aggregations;
118117
}
119118
// endregion

Diff for: src/main/java/org/springframework/data/elasticsearch/core/SearchHitsIterator.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.springframework.data.elasticsearch.core;
1717

18-
import org.elasticsearch.search.aggregations.Aggregations;
1918
import org.springframework.data.util.CloseableIterator;
2019
import org.springframework.lang.Nullable;
2120

@@ -33,7 +32,7 @@ public interface SearchHitsIterator<T> extends CloseableIterator<SearchHit<T>> {
3332
* @return the aggregations.
3433
*/
3534
@Nullable
36-
Aggregations getAggregations();
35+
AggregationsContainer<?> getAggregations();
3736

3837
/**
3938
* @return the maximum score

Diff for: src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.function.Consumer;
2323
import java.util.function.Function;
2424

25-
import org.elasticsearch.search.aggregations.Aggregations;
2625
import org.springframework.data.elasticsearch.client.util.ScrollState;
2726
import org.springframework.lang.Nullable;
2827
import org.springframework.util.Assert;
@@ -55,7 +54,7 @@ static <T> SearchHitsIterator<T> streamResults(int maxCount, SearchScrollHits<T>
5554
Assert.notNull(continueScrollFunction, "continueScrollFunction must not be null.");
5655
Assert.notNull(clearScrollConsumer, "clearScrollConsumer must not be null.");
5756

58-
Aggregations aggregations = searchHits.getAggregations();
57+
AggregationsContainer<?> aggregations = searchHits.getAggregations();
5958
float maxScore = searchHits.getMaxScore();
6059
long totalHits = searchHits.getTotalHits();
6160
TotalHitsRelation totalHitsRelation = searchHits.getTotalHitsRelation();
@@ -78,7 +77,7 @@ public void close() {
7877

7978
@Override
8079
@Nullable
81-
public Aggregations getAggregations() {
80+
public AggregationsContainer<?> getAggregations() {
8281
return aggregations;
8382
}
8483

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.core.clients.elasticsearch7;
17+
18+
import org.elasticsearch.search.aggregations.Aggregation;
19+
import org.springframework.data.elasticsearch.core.AggregationContainer;
20+
import org.springframework.lang.NonNull;
21+
22+
/**
23+
* AggregationContainer implementation for an Elasticsearch7 aggregation.
24+
*
25+
* @author Peter-Josef Meisch
26+
* @since 4.3
27+
*/
28+
public class ElasticsearchAggregation implements AggregationContainer<Aggregation> {
29+
30+
private final Aggregation aggregation;
31+
32+
public ElasticsearchAggregation(Aggregation aggregation) {
33+
this.aggregation = aggregation;
34+
}
35+
36+
@NonNull
37+
@Override
38+
public Aggregation aggregation() {
39+
return aggregation;
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.core.clients.elasticsearch7;
17+
18+
import org.elasticsearch.search.aggregations.Aggregations;
19+
import org.springframework.data.elasticsearch.core.AggregationsContainer;
20+
import org.springframework.lang.NonNull;
21+
22+
/**
23+
* AggregationsContainer implementation for the Elasticsearch7 aggregations.
24+
*
25+
* @author Peter-Josef Meisch
26+
* @since 4.3
27+
*/
28+
public class ElasticsearchAggregations implements AggregationsContainer<Aggregations> {
29+
30+
private final Aggregations aggregations;
31+
32+
public ElasticsearchAggregations(Aggregations aggregations) {
33+
this.aggregations = aggregations;
34+
}
35+
36+
@NonNull
37+
@Override
38+
public Aggregations aggregations() {
39+
return aggregations;
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Classes and interfaces used by the code that uses Elasticsearch 7 client libraries
3+
*/
4+
@org.springframework.lang.NonNullApi
5+
@org.springframework.lang.NonNullFields
6+
package org.springframework.data.elasticsearch.core.clients.elasticsearch7;

0 commit comments

Comments
 (0)