DATAES-727 - Use track_total_hits parameter for count queries.

Original PR: #379
This commit is contained in:
Peter-Josef Meisch 2020-01-10 15:52:03 +01:00 committed by GitHub
parent 7294accaca
commit d55cb00d45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 44 deletions

View File

@ -79,7 +79,6 @@ import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
@ -336,9 +335,10 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
* @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#count(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest)
*/
@Override
public Mono<Long> count(HttpHeaders headers, CountRequest countRequest) {
return sendRequest(countRequest, RequestCreator.count(), CountResponse.class, headers) //
.map(CountResponse::getCount) //
public Mono<Long> count(HttpHeaders headers, SearchRequest searchRequest) {
return sendRequest(searchRequest, RequestCreator.search(), SearchResponse.class, headers) //
.map(SearchResponse::getHits) //
.map(searchHits -> searchHits.getTotalHits().value) //
.next();
}

View File

@ -43,7 +43,6 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
@ -342,37 +341,37 @@ public interface ReactiveElasticsearchClient {
* @return the {@link Mono} emitting the count result.
* @since 4.0
*/
default Mono<Long> count(Consumer<CountRequest> consumer) {
default Mono<Long> count(Consumer<SearchRequest> consumer) {
CountRequest countRequest = new CountRequest();
consumer.accept(countRequest);
return count(countRequest);
SearchRequest searchRequest = new SearchRequest();
consumer.accept(searchRequest);
return count(searchRequest);
}
/**
* Execute a {@link SearchRequest} against the {@literal count} API.
* Execute a {@link SearchRequest} against the {@literal search} API.
*
* @param countRequest must not be {@literal null}.
* @param searchRequest must not be {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html">Count API on
* elastic.co</a>
* @return the {@link Mono} emitting the count result.
* @since 4.0
*/
default Mono<Long> count(CountRequest countRequest) {
return count(HttpHeaders.EMPTY, countRequest);
default Mono<Long> count(SearchRequest searchRequest) {
return count(HttpHeaders.EMPTY, searchRequest);
}
/**
* Execute a {@link SearchRequest} against the {@literal count} API.
* Execute a {@link SearchRequest} against the {@literal search} API.
*
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
* @param countRequest must not be {@literal null}.
* @param searchRequest must not be {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html">Count API on
* elastic.co</a>
* @return the {@link Mono} emitting the count result.
* @since 4.0
*/
Mono<Long> count(HttpHeaders headers, CountRequest countRequest);
Mono<Long> count(HttpHeaders headers, SearchRequest searchRequest);
/**
* Execute a {@link SearchRequest} against the {@literal search} API.

View File

@ -212,8 +212,13 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate {
@Override
public long count(Query query, Class<?> clazz, IndexCoordinates index) {
Assert.notNull(query, "query must not be null");
Assert.notNull(index, "index must not be null");
final boolean trackTotalHits = query.getTrackTotalHits();
query.setTrackTotalHits(true);
SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index);
query.setTrackTotalHits(trackTotalHits);
searchRequest.source().size(0);

View File

@ -185,9 +185,13 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
@Override
public long count(Query query, @Nullable Class<?> clazz, IndexCoordinates index) {
Assert.notNull(query, "query must not be null");
Assert.notNull(index, "index must not be null");
final boolean trackTotalHits = query.getTrackTotalHits();
query.setTrackTotalHits(true);
SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index);
query.setTrackTotalHits(trackTotalHits);
searchRequestBuilder.setSize(0);
return SearchHitsUtil.getTotalCount(getSearchResponse(searchRequestBuilder).getHits());

View File

@ -435,10 +435,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
return Flux.defer(() -> {
SearchRequest request = requestFactory.searchRequest(query, clazz, index);
if (indicesOptions != null) {
request.indicesOptions(indicesOptions);
}
request = prepareSearchRequest(request);
if (query.getPageable().isPaged() || query.isLimiting()) {
return doFind(request);
@ -455,17 +452,18 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
@Override
public Mono<Long> count(Query query, Class<?> entityType, IndexCoordinates index) {
return doCount(query, getPersistentEntityFor(entityType), index);
return doCount(query, entityType, index);
}
private Mono<Long> doCount(Query query, ElasticsearchPersistentEntity<?> entity, IndexCoordinates index) {
private Mono<Long> doCount(Query query, Class<?> entityType, IndexCoordinates index) {
return Mono.defer(() -> {
CountRequest countRequest = buildCountRequest(query, entity, index);
CountRequest request = prepareCountRequest(countRequest);
SearchRequest request = requestFactory.searchRequest(query, entityType, index);
request = prepareSearchRequest(request);
request.source().size(0);
request.source().trackTotalHits(true);
return doCount(request);
});
}
private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity<?> entity, IndexCoordinates index) {
@ -524,17 +522,17 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
/**
* Customization hook on the actual execution result {@link Publisher}. <br />
*
* @param request the already prepared {@link CountRequest} ready to be executed.
* @param request the already prepared {@link SearchRequest} ready to be executed.
* @return a {@link Mono} emitting the result of the operation.
*/
protected Mono<Long> doCount(CountRequest request) {
protected Mono<Long> doCount(SearchRequest request) {
if (QUERY_LOGGER.isDebugEnabled()) {
QUERY_LOGGER.debug("Executing doCount: {}", request);
}
return Mono.from(execute(client -> client.count(request))) //
.onErrorResume(NoSuchIndexException.class, it -> Mono.empty());
.onErrorResume(NoSuchIndexException.class, it -> Mono.just(0L));
}
/**
@ -608,22 +606,6 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
return mappedSort;
}
/**
* Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the
* {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable.
*
* @param request the generated {@link CountRequest}.
* @return never {@literal null}.
*/
protected CountRequest prepareCountRequest(CountRequest request) {
if (indicesOptions == null) {
return request;
}
return request.indicesOptions(indicesOptions);
}
/**
* Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the
* {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable.