diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 47d129f6c..552bd4544 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -732,13 +732,15 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera private Flux doFind(Query query, Class clazz, IndexCoordinates index) { return Flux.defer(() -> { - SearchRequest request = requestFactory.searchRequest(query, clazz, index); - request = prepareSearchRequest(request); - if (query.getPageable().isPaged() || query.isLimiting()) { - return doFind(request); - } else { + SearchRequest request = requestFactory.searchRequest(query, clazz, index); + boolean useScroll = !(query.getPageable().isPaged() || query.isLimiting()); + request = prepareSearchRequest(request, useScroll); + + if (useScroll) { return doScroll(request); + } else { + return doFind(request); } }); } @@ -747,7 +749,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera return Mono.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, clazz, index); - request = prepareSearchRequest(request); + request = prepareSearchRequest(request, false); return doFindForResponse(request); }); } @@ -782,7 +784,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera private Flux doAggregate(Query query, Class entityType, IndexCoordinates index) { return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, entityType, index); - request = prepareSearchRequest(request); + request = prepareSearchRequest(request, false); return doAggregate(request); }); } @@ -801,7 +803,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera return Mono.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, entityType, index); - request = prepareSearchRequest(request); + request = prepareSearchRequest(request, false); return doCount(request); }); } @@ -890,15 +892,21 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. * * @param request the generated {@link SearchRequest}. + * @param useScroll * @return never {@literal null}. */ - protected SearchRequest prepareSearchRequest(SearchRequest request) { + protected SearchRequest prepareSearchRequest(SearchRequest request, boolean useScroll) { - if (indicesOptions == null) { - return request; + if (indicesOptions != null) { + request = request.indicesOptions(indicesOptions); } - return request.indicesOptions(indicesOptions); + // request_cache is not allowed on scroll requests. + if (useScroll) { + request = request.requestCache(null); + } + return request; + } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index c42b93f6b..386784d62 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -1001,6 +1001,10 @@ class RequestFactory { query.getRescorerQueries().forEach(rescorer -> sourceBuilder.addRescorer(getQueryRescorerBuilder(rescorer))); + if (query.getRequestCache() != null) { + request.requestCache(query.getRequestCache()); + } + request.source(sourceBuilder); return request; } @@ -1089,6 +1093,10 @@ class RequestFactory { query.getRescorerQueries().forEach(rescorer -> searchRequestBuilder.addRescorer(getQueryRescorerBuilder(rescorer))); + if (query.getRequestCache() != null) { + searchRequestBuilder.setRequestCache(query.getRequestCache()); + } + return searchRequestBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 1d3e9fb49..3e5f1a386 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -65,6 +65,7 @@ abstract class AbstractQuery implements Query { private boolean explain = false; @Nullable private List searchAfter; protected List rescorerQueries = new ArrayList<>(); + @Nullable protected Boolean requestCache; @Override @Nullable @@ -328,4 +329,15 @@ abstract class AbstractQuery implements Query { public List getRescorerQueries() { return rescorerQueries; } + + @Override + public void setRequestCache(@Nullable Boolean value) { + this.requestCache = value; + } + + @Override + @Nullable + public Boolean getRequestCache() { + return this.requestCache; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index cbb10eb98..1f255ffb1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -105,6 +105,7 @@ public interface Query { /** * Set fields to be returned as part of search request + * * @param fields must not be {@literal null} * @since 4.3 */ @@ -344,4 +345,19 @@ public interface Query { default List getRescorerQueries() { return Collections.emptyList(); } + + /** + * sets the request_cache value for the query. + * + * @param value new value + * @since 4.3 + */ + void setRequestCache(@Nullable Boolean value); + + /** + * @return the request_cache value for this query. + * @since 4.3 + */ + @Nullable + Boolean getRequestCache(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index ffc7ef184..001811b97 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -81,6 +81,7 @@ import org.springframework.lang.Nullable; * @author Roman Puchkovskiy * @author Peer Mueller */ +@SuppressWarnings("ConstantConditions") @ExtendWith(MockitoExtension.class) class RequestFactoryTests { @@ -595,6 +596,54 @@ class RequestFactoryTests { assertEquals(expected, searchRequest, false); } + @Test // #1564 + @DisplayName("should not set request_cache on default SearchRequest") + void shouldNotSetRequestCacheOnDefaultSearchRequest() { + + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + + SearchRequest searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, Person.class, + IndexCoordinates.of("persons")); + + assertThat(searchRequest.requestCache()).isNull(); + assertThat(searchRequestBuilder.request().requestCache()).isNull(); + } + + @Test // #1564 + @DisplayName("should set request_cache true on SearchRequest") + void shouldSetRequestCacheTrueOnSearchRequest() { + + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + query.setRequestCache(true); + + SearchRequest searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, Person.class, + IndexCoordinates.of("persons")); + + assertThat(searchRequest.requestCache()).isTrue(); + assertThat(searchRequestBuilder.request().requestCache()).isTrue(); + } + + @Test // #1564 + @DisplayName("should set request_cache false on SearchRequest") + void shouldSetRequestCacheFalseOnSearchRequest() { + + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + query.setRequestCache(false); + + SearchRequest searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, Person.class, + IndexCoordinates.of("persons")); + + assertThat(searchRequest.requestCache()).isFalse(); + assertThat(searchRequestBuilder.request().requestCache()).isFalse(); + } + + // region entities static class Person { @Nullable @Id String id; @Nullable @Field(name = "last-name") String lastName; @@ -644,4 +693,5 @@ class RequestFactoryTests { static class EntityWithSeqNoPrimaryTerm { @Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm; } + // endregion }