mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-30 15:52:12 +00:00
Add support for retrieving request executionDuration.
Original Pull Request #2991 Closes #2986
This commit is contained in:
parent
172933af8e
commit
d2ab03e6a4
@ -81,7 +81,7 @@ When a document is retrieved with the methods of the `DocumentOperations` inter
|
|||||||
When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity.
|
When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity.
|
||||||
|
|
||||||
In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information.
|
In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information.
|
||||||
These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations.
|
These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations or the execution duration it took to complete the request.
|
||||||
The following classes and interfaces are now available:
|
The following classes and interfaces are now available:
|
||||||
|
|
||||||
.SearchHit<T>
|
.SearchHit<T>
|
||||||
|
@ -50,6 +50,7 @@ import org.springframework.util.Assert;
|
|||||||
*
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.4
|
* @since 4.4
|
||||||
*/
|
*/
|
||||||
final class DocumentAdapters {
|
final class DocumentAdapters {
|
||||||
@ -74,7 +75,7 @@ final class DocumentAdapters {
|
|||||||
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
|
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
|
||||||
hit.innerHits().forEach((name, innerHitsResult) -> {
|
hit.innerHits().forEach((name, innerHitsResult) -> {
|
||||||
// noinspection ReturnOfNull
|
// 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));
|
searchDocument -> null, jsonpMapper));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import co.elastic.clients.elasticsearch.core.search.Suggestion;
|
|||||||
import co.elastic.clients.elasticsearch.core.search.TotalHits;
|
import co.elastic.clients.elasticsearch.core.search.TotalHits;
|
||||||
import co.elastic.clients.json.JsonpMapper;
|
import co.elastic.clients.json.JsonpMapper;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -56,6 +57,7 @@ import org.springframework.util.CollectionUtils;
|
|||||||
*
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.4
|
* @since 4.4
|
||||||
*/
|
*/
|
||||||
class SearchDocumentResponseBuilder {
|
class SearchDocumentResponseBuilder {
|
||||||
@ -83,8 +85,10 @@ class SearchDocumentResponseBuilder {
|
|||||||
Map<String, List<Suggestion<EntityAsMap>>> suggest = responseBody.suggest();
|
Map<String, List<Suggestion<EntityAsMap>>> suggest = responseBody.suggest();
|
||||||
var pointInTimeId = responseBody.pitId();
|
var pointInTimeId = responseBody.pitId();
|
||||||
var shards = responseBody.shards();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,8 +113,10 @@ class SearchDocumentResponseBuilder {
|
|||||||
var aggregations = response.aggregations();
|
var aggregations = response.aggregations();
|
||||||
var suggest = response.suggest();
|
var suggest = response.suggest();
|
||||||
var pointInTimeId = response.pitId();
|
var pointInTimeId = response.pitId();
|
||||||
|
var executionDurationInMillis = response.took();
|
||||||
|
|
||||||
return from(hitsMetadata, shards, scrollId, pointInTimeId, aggregations, suggest, entityCreator, jsonpMapper);
|
return from(hitsMetadata, shards, scrollId, pointInTimeId, executionDurationInMillis, aggregations, suggest,
|
||||||
|
entityCreator, jsonpMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +133,7 @@ class SearchDocumentResponseBuilder {
|
|||||||
* @return the {@link SearchDocumentResponse}
|
* @return the {@link SearchDocumentResponse}
|
||||||
*/
|
*/
|
||||||
public static <T> SearchDocumentResponse from(HitsMetadata<?> hitsMetadata, @Nullable ShardStatistics shards,
|
public static <T> SearchDocumentResponse from(HitsMetadata<?> hitsMetadata, @Nullable ShardStatistics shards,
|
||||||
@Nullable String scrollId, @Nullable String pointInTimeId, @Nullable Map<String, Aggregate> aggregations,
|
@Nullable String scrollId, @Nullable String pointInTimeId, long executionDurationInMillis, @Nullable Map<String, Aggregate> aggregations,
|
||||||
Map<String, List<Suggestion<EntityAsMap>>> suggestES, SearchDocumentResponse.EntityCreator<T> entityCreator,
|
Map<String, List<Suggestion<EntityAsMap>>> suggestES, SearchDocumentResponse.EntityCreator<T> entityCreator,
|
||||||
JsonpMapper jsonpMapper) {
|
JsonpMapper jsonpMapper) {
|
||||||
|
|
||||||
@ -151,6 +157,8 @@ class SearchDocumentResponseBuilder {
|
|||||||
|
|
||||||
float maxScore = hitsMetadata.maxScore() != null ? hitsMetadata.maxScore().floatValue() : Float.NaN;
|
float maxScore = hitsMetadata.maxScore() != null ? hitsMetadata.maxScore().floatValue() : Float.NaN;
|
||||||
|
|
||||||
|
Duration executionDuration = Duration.ofMillis(executionDurationInMillis);
|
||||||
|
|
||||||
List<SearchDocument> searchDocuments = new ArrayList<>();
|
List<SearchDocument> searchDocuments = new ArrayList<>();
|
||||||
for (Hit<?> hit : hitsMetadata.hits()) {
|
for (Hit<?> hit : hitsMetadata.hits()) {
|
||||||
searchDocuments.add(DocumentAdapters.from(hit, jsonpMapper));
|
searchDocuments.add(DocumentAdapters.from(hit, jsonpMapper));
|
||||||
@ -163,7 +171,7 @@ class SearchDocumentResponseBuilder {
|
|||||||
|
|
||||||
SearchShardStatistics shardStatistics = shards != null ? shardsFrom(shards) : null;
|
SearchShardStatistics shardStatistics = shards != null ? shardsFrom(shards) : null;
|
||||||
|
|
||||||
return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, pointInTimeId, searchDocuments,
|
return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, executionDuration, scrollId, pointInTimeId, searchDocuments,
|
||||||
aggregationsContainer, suggest, shardStatistics);
|
aggregationsContainer, suggest, shardStatistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ package org.springframework.data.elasticsearch.core;
|
|||||||
|
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ import org.springframework.lang.Nullable;
|
|||||||
*
|
*
|
||||||
* @param <T> the result data class.
|
* @param <T> the result data class.
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.4
|
* @since 4.4
|
||||||
*/
|
*/
|
||||||
public interface ReactiveSearchHits<T> {
|
public interface ReactiveSearchHits<T> {
|
||||||
@ -37,6 +40,11 @@ public interface ReactiveSearchHits<T> {
|
|||||||
|
|
||||||
float getMaxScore();
|
float getMaxScore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the execution duration it took to complete the request
|
||||||
|
*/
|
||||||
|
Duration getExecutionDuration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the {@link SearchHit}s from the search result.
|
* @return the {@link SearchHit}s from the search result.
|
||||||
*/
|
*/
|
||||||
|
@ -17,11 +17,14 @@ package org.springframework.data.elasticsearch.core;
|
|||||||
|
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.4
|
* @since 4.4
|
||||||
*/
|
*/
|
||||||
public class ReactiveSearchHitsImpl<T> implements ReactiveSearchHits<T> {
|
public class ReactiveSearchHitsImpl<T> implements ReactiveSearchHits<T> {
|
||||||
@ -58,6 +61,11 @@ public class ReactiveSearchHitsImpl<T> implements ReactiveSearchHits<T> {
|
|||||||
return delegate.getMaxScore();
|
return delegate.getMaxScore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getExecutionDuration() {
|
||||||
|
return delegate.getExecutionDuration();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSearchHits() {
|
public boolean hasSearchHits() {
|
||||||
return delegate.hasSearchHits();
|
return delegate.hasSearchHits();
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core;
|
package org.springframework.data.elasticsearch.core;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -47,6 +48,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Sascha Woo
|
* @author Sascha Woo
|
||||||
* @author Jakob Hoeper
|
* @author Jakob Hoeper
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class SearchHitMapping<T> {
|
public class SearchHitMapping<T> {
|
||||||
@ -87,6 +89,7 @@ public class SearchHitMapping<T> {
|
|||||||
long totalHits = searchDocumentResponse.getTotalHits();
|
long totalHits = searchDocumentResponse.getTotalHits();
|
||||||
SearchShardStatistics shardStatistics = searchDocumentResponse.getSearchShardStatistics();
|
SearchShardStatistics shardStatistics = searchDocumentResponse.getSearchShardStatistics();
|
||||||
float maxScore = searchDocumentResponse.getMaxScore();
|
float maxScore = searchDocumentResponse.getMaxScore();
|
||||||
|
Duration executionDuration = searchDocumentResponse.getExecutionDuration();
|
||||||
String scrollId = searchDocumentResponse.getScrollId();
|
String scrollId = searchDocumentResponse.getScrollId();
|
||||||
String pointInTimeId = searchDocumentResponse.getPointInTimeId();
|
String pointInTimeId = searchDocumentResponse.getPointInTimeId();
|
||||||
|
|
||||||
@ -104,8 +107,8 @@ public class SearchHitMapping<T> {
|
|||||||
Suggest suggest = searchDocumentResponse.getSuggest();
|
Suggest suggest = searchDocumentResponse.getSuggest();
|
||||||
mapHitsInCompletionSuggestion(suggest);
|
mapHitsInCompletionSuggestion(suggest);
|
||||||
|
|
||||||
return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, pointInTimeId, searchHits,
|
return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, executionDuration, scrollId, pointInTimeId,
|
||||||
aggregations, suggest, shardStatistics);
|
searchHits, aggregations, suggest, shardStatistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -238,6 +241,7 @@ public class SearchHitMapping<T> {
|
|||||||
return new SearchHitsImpl<>(searchHits.getTotalHits(),
|
return new SearchHitsImpl<>(searchHits.getTotalHits(),
|
||||||
searchHits.getTotalHitsRelation(),
|
searchHits.getTotalHitsRelation(),
|
||||||
searchHits.getMaxScore(),
|
searchHits.getMaxScore(),
|
||||||
|
searchHits.getExecutionDuration(),
|
||||||
scrollId,
|
scrollId,
|
||||||
searchHits.getPointInTimeId(),
|
searchHits.getPointInTimeId(),
|
||||||
convertedSearchHits,
|
convertedSearchHits,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core;
|
package org.springframework.data.elasticsearch.core;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ import org.springframework.lang.Nullable;
|
|||||||
* @param <T> the result data class.
|
* @param <T> the result data class.
|
||||||
* @author Sascha Woo
|
* @author Sascha Woo
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public interface SearchHits<T> extends Streamable<SearchHit<T>> {
|
public interface SearchHits<T> extends Streamable<SearchHit<T>> {
|
||||||
@ -43,6 +45,11 @@ public interface SearchHits<T> extends Streamable<SearchHit<T>> {
|
|||||||
*/
|
*/
|
||||||
float getMaxScore();
|
float getMaxScore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the execution duration it took to complete the request
|
||||||
|
*/
|
||||||
|
Duration getExecutionDuration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index position in List.
|
* @param index position in List.
|
||||||
* @return the {@link SearchHit} at position {index}
|
* @return the {@link SearchHit} at position {index}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core;
|
package org.springframework.data.elasticsearch.core;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Sascha Woo
|
* @author Sascha Woo
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
||||||
@ -37,6 +39,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
|||||||
private final long totalHits;
|
private final long totalHits;
|
||||||
private final TotalHitsRelation totalHitsRelation;
|
private final TotalHitsRelation totalHitsRelation;
|
||||||
private final float maxScore;
|
private final float maxScore;
|
||||||
|
private final Duration executionDuration;
|
||||||
@Nullable private final String scrollId;
|
@Nullable private final String scrollId;
|
||||||
private final List<? extends SearchHit<T>> searchHits;
|
private final List<? extends SearchHit<T>> searchHits;
|
||||||
private final Lazy<List<SearchHit<T>>> unmodifiableSearchHits;
|
private final Lazy<List<SearchHit<T>>> unmodifiableSearchHits;
|
||||||
@ -49,12 +52,13 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
|||||||
* @param totalHits the number of total hits for the search
|
* @param totalHits the number of total hits for the search
|
||||||
* @param totalHitsRelation the relation {@see TotalHitsRelation}, must not be {@literal null}
|
* @param totalHitsRelation the relation {@see TotalHitsRelation}, must not be {@literal null}
|
||||||
* @param maxScore the maximum score
|
* @param maxScore the maximum score
|
||||||
|
* @param executionDuration the execution duration it took to complete the request
|
||||||
* @param scrollId the scroll id if available
|
* @param scrollId the scroll id if available
|
||||||
* @param searchHits must not be {@literal null}
|
* @param searchHits must not be {@literal null}
|
||||||
* @param aggregations the aggregations if available
|
* @param aggregations the aggregations if available
|
||||||
*/
|
*/
|
||||||
public SearchHitsImpl(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, @Nullable String scrollId,
|
public SearchHitsImpl(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, Duration executionDuration,
|
||||||
@Nullable String pointInTimeId, List<? extends SearchHit<T>> searchHits,
|
@Nullable String scrollId, @Nullable String pointInTimeId, List<? extends SearchHit<T>> searchHits,
|
||||||
@Nullable AggregationsContainer<?> aggregations, @Nullable Suggest suggest,
|
@Nullable AggregationsContainer<?> aggregations, @Nullable Suggest suggest,
|
||||||
@Nullable SearchShardStatistics searchShardStatistics) {
|
@Nullable SearchShardStatistics searchShardStatistics) {
|
||||||
|
|
||||||
@ -63,6 +67,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
|||||||
this.totalHits = totalHits;
|
this.totalHits = totalHits;
|
||||||
this.totalHitsRelation = totalHitsRelation;
|
this.totalHitsRelation = totalHitsRelation;
|
||||||
this.maxScore = maxScore;
|
this.maxScore = maxScore;
|
||||||
|
this.executionDuration = executionDuration;
|
||||||
this.scrollId = scrollId;
|
this.scrollId = scrollId;
|
||||||
this.pointInTimeId = pointInTimeId;
|
this.pointInTimeId = pointInTimeId;
|
||||||
this.searchHits = searchHits;
|
this.searchHits = searchHits;
|
||||||
@ -88,6 +93,11 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
|||||||
return maxScore;
|
return maxScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getExecutionDuration() {
|
||||||
|
return executionDuration;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getScrollId() {
|
public String getScrollId() {
|
||||||
@ -133,6 +143,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
|||||||
"totalHits=" + totalHits + //
|
"totalHits=" + totalHits + //
|
||||||
", totalHitsRelation=" + totalHitsRelation + //
|
", totalHitsRelation=" + totalHitsRelation + //
|
||||||
", maxScore=" + maxScore + //
|
", maxScore=" + maxScore + //
|
||||||
|
", executionDuration=" + executionDuration + //
|
||||||
", scrollId='" + scrollId + '\'' + //
|
", scrollId='" + scrollId + '\'' + //
|
||||||
", pointInTimeId='" + pointInTimeId + '\'' + //
|
", pointInTimeId='" + pointInTimeId + '\'' + //
|
||||||
", searchHits={" + searchHits.size() + " elements}" + //
|
", searchHits={" + searchHits.size() + " elements}" + //
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core;
|
package org.springframework.data.elasticsearch.core;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
import org.springframework.data.util.CloseableIterator;
|
import org.springframework.data.util.CloseableIterator;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
@ -23,6 +25,7 @@ import org.springframework.lang.Nullable;
|
|||||||
* {@link java.util.stream.Stream}.
|
* {@link java.util.stream.Stream}.
|
||||||
*
|
*
|
||||||
* @author Sascha Woo
|
* @author Sascha Woo
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
@ -39,6 +42,11 @@ public interface SearchHitsIterator<T> extends CloseableIterator<SearchHit<T>> {
|
|||||||
*/
|
*/
|
||||||
float getMaxScore();
|
float getMaxScore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the execution duration it took to complete the request
|
||||||
|
*/
|
||||||
|
Duration getExecutionDuration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of total hits.
|
* @return the number of total hits.
|
||||||
*/
|
*/
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core;
|
package org.springframework.data.elasticsearch.core;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
@ -31,6 +32,7 @@ import org.springframework.util.Assert;
|
|||||||
*
|
*
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Sascha Woo
|
* @author Sascha Woo
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
abstract class StreamQueries {
|
abstract class StreamQueries {
|
||||||
@ -56,6 +58,7 @@ abstract class StreamQueries {
|
|||||||
|
|
||||||
AggregationsContainer<?> aggregations = searchHits.getAggregations();
|
AggregationsContainer<?> aggregations = searchHits.getAggregations();
|
||||||
float maxScore = searchHits.getMaxScore();
|
float maxScore = searchHits.getMaxScore();
|
||||||
|
Duration executionDuration = searchHits.getExecutionDuration();
|
||||||
long totalHits = searchHits.getTotalHits();
|
long totalHits = searchHits.getTotalHits();
|
||||||
TotalHitsRelation totalHitsRelation = searchHits.getTotalHitsRelation();
|
TotalHitsRelation totalHitsRelation = searchHits.getTotalHitsRelation();
|
||||||
|
|
||||||
@ -86,6 +89,11 @@ abstract class StreamQueries {
|
|||||||
return maxScore;
|
return maxScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getExecutionDuration() {
|
||||||
|
return executionDuration;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTotalHits() {
|
public long getTotalHits() {
|
||||||
return totalHits;
|
return totalHits;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core.document;
|
package org.springframework.data.elasticsearch.core.document;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -29,6 +30,7 @@ import org.springframework.lang.Nullable;
|
|||||||
*
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class SearchDocumentResponse {
|
public class SearchDocumentResponse {
|
||||||
@ -36,6 +38,7 @@ public class SearchDocumentResponse {
|
|||||||
private final long totalHits;
|
private final long totalHits;
|
||||||
private final String totalHitsRelation;
|
private final String totalHitsRelation;
|
||||||
private final float maxScore;
|
private final float maxScore;
|
||||||
|
private final Duration executionDuration;
|
||||||
@Nullable private final String scrollId;
|
@Nullable private final String scrollId;
|
||||||
private final List<SearchDocument> searchDocuments;
|
private final List<SearchDocument> searchDocuments;
|
||||||
@Nullable private final AggregationsContainer<?> aggregations;
|
@Nullable private final AggregationsContainer<?> aggregations;
|
||||||
@ -44,13 +47,14 @@ public class SearchDocumentResponse {
|
|||||||
@Nullable String pointInTimeId;
|
@Nullable String pointInTimeId;
|
||||||
@Nullable private final SearchShardStatistics searchShardStatistics;
|
@Nullable private final SearchShardStatistics searchShardStatistics;
|
||||||
|
|
||||||
public SearchDocumentResponse(long totalHits, String totalHitsRelation, float maxScore, @Nullable String scrollId,
|
public SearchDocumentResponse(long totalHits, String totalHitsRelation, float maxScore, Duration executionDuration,
|
||||||
@Nullable String pointInTimeId, List<SearchDocument> searchDocuments,
|
@Nullable String scrollId, @Nullable String pointInTimeId, List<SearchDocument> searchDocuments,
|
||||||
@Nullable AggregationsContainer<?> aggregationsContainer, @Nullable Suggest suggest,
|
@Nullable AggregationsContainer<?> aggregationsContainer, @Nullable Suggest suggest,
|
||||||
@Nullable SearchShardStatistics searchShardStatistics) {
|
@Nullable SearchShardStatistics searchShardStatistics) {
|
||||||
this.totalHits = totalHits;
|
this.totalHits = totalHits;
|
||||||
this.totalHitsRelation = totalHitsRelation;
|
this.totalHitsRelation = totalHitsRelation;
|
||||||
this.maxScore = maxScore;
|
this.maxScore = maxScore;
|
||||||
|
this.executionDuration = executionDuration;
|
||||||
this.scrollId = scrollId;
|
this.scrollId = scrollId;
|
||||||
this.pointInTimeId = pointInTimeId;
|
this.pointInTimeId = pointInTimeId;
|
||||||
this.searchDocuments = searchDocuments;
|
this.searchDocuments = searchDocuments;
|
||||||
@ -71,6 +75,10 @@ public class SearchDocumentResponse {
|
|||||||
return maxScore;
|
return maxScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Duration getExecutionDuration() {
|
||||||
|
return executionDuration;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getScrollId() {
|
public String getScrollId() {
|
||||||
return scrollId;
|
return scrollId;
|
||||||
|
@ -44,6 +44,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
*
|
*
|
||||||
* @author Sébastien Comeau
|
* @author Sébastien Comeau
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
*/
|
*/
|
||||||
class SearchDocumentResponseBuilderUnitTests {
|
class SearchDocumentResponseBuilderUnitTests {
|
||||||
@ -54,35 +55,21 @@ class SearchDocumentResponseBuilderUnitTests {
|
|||||||
void shouldGetPhraseSuggestion() throws JSONException {
|
void shouldGetPhraseSuggestion() throws JSONException {
|
||||||
// arrange
|
// arrange
|
||||||
final var hitsMetadata = new HitsMetadata.Builder<EntityAsMap>()
|
final var hitsMetadata = new HitsMetadata.Builder<EntityAsMap>()
|
||||||
.total(total -> total
|
.total(total -> total.value(0).relation(TotalHitsRelation.Eq)).hits(new ArrayList<>()).build();
|
||||||
.value(0)
|
|
||||||
.relation(TotalHitsRelation.Eq))
|
|
||||||
.hits(new ArrayList<>())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
final var suggestionTest = new Suggestion.Builder<EntityAsMap>()
|
final var suggestionTest = new Suggestion.Builder<EntityAsMap>().phrase(phrase -> phrase.text("National").offset(0)
|
||||||
.phrase(phrase -> phrase
|
|
||||||
.text("National")
|
|
||||||
.offset(0)
|
|
||||||
.length(8)
|
.length(8)
|
||||||
.options(option -> option
|
.options(
|
||||||
.text("nations")
|
option -> option.text("nations").highlighted("highlighted-nations").score(0.11480146).collateMatch(false))
|
||||||
.highlighted("highlighted-nations")
|
.options(option -> option.text("national").highlighted("highlighted-national").score(0.08063514)
|
||||||
.score(0.11480146)
|
|
||||||
.collateMatch(false))
|
|
||||||
.options(option -> option
|
|
||||||
.text("national")
|
|
||||||
.highlighted("highlighted-national")
|
|
||||||
.score(0.08063514)
|
|
||||||
.collateMatch(false)))
|
.collateMatch(false)))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var sortProperties = ImmutableMap.<String, List<Suggestion<EntityAsMap>>> builder()
|
final var sortProperties = ImmutableMap.<String, List<Suggestion<EntityAsMap>>> builder()
|
||||||
.put("suggestionTest", ImmutableList.of(suggestionTest))
|
.put("suggestionTest", ImmutableList.of(suggestionTest)).build();
|
||||||
.build();
|
|
||||||
|
|
||||||
// act
|
// 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);
|
jsonpMapper);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
@ -122,35 +109,19 @@ class SearchDocumentResponseBuilderUnitTests {
|
|||||||
void shouldGetShardStatisticsInfo() {
|
void shouldGetShardStatisticsInfo() {
|
||||||
// arrange
|
// arrange
|
||||||
HitsMetadata<EntityAsMap> hitsMetadata = new HitsMetadata.Builder<EntityAsMap>()
|
HitsMetadata<EntityAsMap> hitsMetadata = new HitsMetadata.Builder<EntityAsMap>()
|
||||||
.total(t -> t
|
.total(t -> t.value(0).relation(TotalHitsRelation.Eq)).hits(new ArrayList<>()).build();
|
||||||
.value(0)
|
|
||||||
.relation(TotalHitsRelation.Eq))
|
|
||||||
.hits(new ArrayList<>())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShardStatistics shards = new ShardStatistics.Builder()
|
ShardStatistics shards = new ShardStatistics.Builder().total(15).successful(14).skipped(0).failed(1)
|
||||||
.total(15)
|
.failures(List.of(ShardFailure.of(sfb -> sfb.index("test-index").node("test-node").shard(1)
|
||||||
.successful(14)
|
.reason(rb -> rb.reason("this is a mock failure in shards")
|
||||||
.skipped(0)
|
.causedBy(cbb -> cbb.reason("inner reason").metadata(Map.of("hello", JsonData.of("world"))))
|
||||||
.failed(1)
|
|
||||||
.failures(List.of(
|
|
||||||
ShardFailure.of(sfb -> sfb
|
|
||||||
.index("test-index")
|
|
||||||
.node("test-node")
|
|
||||||
.shard(1)
|
|
||||||
.reason(rb -> rb
|
|
||||||
.reason("this is a mock failure in shards")
|
|
||||||
.causedBy(cbb -> cbb.reason("inner reason")
|
|
||||||
.metadata(Map.of("hello", JsonData.of("world"))))
|
|
||||||
.type("reason-type")
|
.type("reason-type")
|
||||||
|
|
||||||
)
|
).status("fail")))).build();
|
||||||
.status("fail"))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// act
|
// act
|
||||||
SearchDocumentResponse response = SearchDocumentResponseBuilder.from(hitsMetadata, shards, null, null,
|
SearchDocumentResponse response = SearchDocumentResponseBuilder.from(hitsMetadata, shards, null, null, 0, null,
|
||||||
null, null, null, jsonpMapper);
|
null, null, jsonpMapper);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
SearchShardStatistics shardStatistics = response.getSearchShardStatistics();
|
SearchShardStatistics shardStatistics = response.getSearchShardStatistics();
|
||||||
@ -164,11 +135,9 @@ class SearchDocumentResponseBuilderUnitTests {
|
|||||||
assertThat(failures.size()).isEqualTo(1);
|
assertThat(failures.size()).isEqualTo(1);
|
||||||
assertThat(failures).extracting(SearchShardStatistics.Failure::getIndex).containsExactly("test-index");
|
assertThat(failures).extracting(SearchShardStatistics.Failure::getIndex).containsExactly("test-index");
|
||||||
assertThat(failures).extracting(SearchShardStatistics.Failure::getElasticsearchErrorCause)
|
assertThat(failures).extracting(SearchShardStatistics.Failure::getElasticsearchErrorCause)
|
||||||
.extracting(ElasticsearchErrorCause::getReason)
|
.extracting(ElasticsearchErrorCause::getReason).containsExactly("this is a mock failure in shards");
|
||||||
.containsExactly("this is a mock failure in shards");
|
|
||||||
assertThat(failures).extracting(SearchShardStatistics.Failure::getElasticsearchErrorCause)
|
assertThat(failures).extracting(SearchShardStatistics.Failure::getElasticsearchErrorCause)
|
||||||
.extracting(ElasticsearchErrorCause::getCausedBy)
|
.extracting(ElasticsearchErrorCause::getCausedBy).extracting(ElasticsearchErrorCause::getReason)
|
||||||
.extracting(ElasticsearchErrorCause::getReason)
|
|
||||||
.containsExactly("inner reason");
|
.containsExactly("inner reason");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import static org.springframework.data.elasticsearch.core.query.StringQuery.*;
|
|||||||
import static org.springframework.data.elasticsearch.utils.IdGenerator.*;
|
import static org.springframework.data.elasticsearch.utils.IdGenerator.*;
|
||||||
import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
|
import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
@ -99,6 +100,7 @@ import org.springframework.lang.Nullable;
|
|||||||
* @author scoobyzhang
|
* @author scoobyzhang
|
||||||
* @author Hamid Rahimi
|
* @author Hamid Rahimi
|
||||||
* @author Illia Ulianov
|
* @author Illia Ulianov
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
*/
|
*/
|
||||||
@SpringIntegrationTest
|
@SpringIntegrationTest
|
||||||
public abstract class ElasticsearchIntegrationTests {
|
public abstract class ElasticsearchIntegrationTests {
|
||||||
@ -1855,7 +1857,7 @@ public abstract class ElasticsearchIntegrationTests {
|
|||||||
protected abstract Query getBoolQueryWithWildcardsFirstMustSecondShouldAndMinScore(String firstField,
|
protected abstract Query getBoolQueryWithWildcardsFirstMustSecondShouldAndMinScore(String firstField,
|
||||||
String firstValue, String secondField, String secondValue, float minScore);
|
String firstValue, String secondField, String secondValue, float minScore);
|
||||||
|
|
||||||
@Test // DATAES-462
|
@Test // DATAES-462, #2986
|
||||||
public void shouldReturnScores() {
|
public void shouldReturnScores() {
|
||||||
|
|
||||||
List<IndexQuery> indexQueries = new ArrayList<>();
|
List<IndexQuery> indexQueries = new ArrayList<>();
|
||||||
@ -1872,6 +1874,7 @@ public abstract class ElasticsearchIntegrationTests {
|
|||||||
IndexCoordinates.of(indexNameProvider.indexName()));
|
IndexCoordinates.of(indexNameProvider.indexName()));
|
||||||
|
|
||||||
assertThat(searchHits.getMaxScore()).isGreaterThan(0f);
|
assertThat(searchHits.getMaxScore()).isGreaterThan(0f);
|
||||||
|
assertThat(searchHits.getExecutionDuration().toMillis()).isGreaterThan(0);
|
||||||
assertThat(searchHits.getSearchHit(0).getScore()).isGreaterThan(0f);
|
assertThat(searchHits.getSearchHit(0).getScore()).isGreaterThan(0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import static java.util.Collections.*;
|
|||||||
import static org.assertj.core.api.Assertions.*;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -33,6 +34,7 @@ import org.springframework.data.util.CloseableIterator;
|
|||||||
* @author Roman Puchkovskiy
|
* @author Roman Puchkovskiy
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
*/
|
*/
|
||||||
class SearchHitSupportTest {
|
class SearchHitSupportTest {
|
||||||
|
|
||||||
@ -65,8 +67,8 @@ class SearchHitSupportTest {
|
|||||||
hits.add(new SearchHit<>(null, null, null, 0, null, null, null, null, null, null, "four"));
|
hits.add(new SearchHit<>(null, null, null, 0, null, null, null, null, null, null, "four"));
|
||||||
hits.add(new SearchHit<>(null, null, null, 0, null, null, null, null, null, null, "five"));
|
hits.add(new SearchHit<>(null, null, null, 0, null, null, null, null, null, null, "five"));
|
||||||
|
|
||||||
SearchHits<String> originalSearchHits = new SearchHitsImpl<>(hits.size(), TotalHitsRelation.EQUAL_TO, 0, "scroll",
|
SearchHits<String> originalSearchHits = new SearchHitsImpl<>(hits.size(), TotalHitsRelation.EQUAL_TO, 0,
|
||||||
null, hits, null, null, null);
|
Duration.ofMillis(1), "scroll", null, hits, null, null, null);
|
||||||
|
|
||||||
SearchPage<String> searchPage = SearchHitSupport.searchPageFor(originalSearchHits, PageRequest.of(0, 3));
|
SearchPage<String> searchPage = SearchHitSupport.searchPageFor(originalSearchHits, PageRequest.of(0, 3));
|
||||||
SearchHits<String> searchHits = searchPage.getSearchHits();
|
SearchHits<String> searchHits = searchPage.getSearchHits();
|
||||||
@ -89,6 +91,11 @@ class SearchHitSupportTest {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getExecutionDuration() {
|
||||||
|
return Duration.ofMillis(1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTotalHits() {
|
public long getTotalHits() {
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -32,6 +33,7 @@ import org.springframework.data.util.StreamUtils;
|
|||||||
* @author Sascha Woo
|
* @author Sascha Woo
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
|
* @author Mohamed El Harrougui
|
||||||
*/
|
*/
|
||||||
public class StreamQueriesTest {
|
public class StreamQueriesTest {
|
||||||
|
|
||||||
@ -181,6 +183,7 @@ public class StreamQueriesTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SearchScrollHits<String> newSearchScrollHits(List<SearchHit<String>> hits, String scrollId) {
|
private SearchScrollHits<String> newSearchScrollHits(List<SearchHit<String>> hits, String scrollId) {
|
||||||
return new SearchHitsImpl<>(hits.size(), TotalHitsRelation.EQUAL_TO, 0, scrollId, null, hits, null, null, null);
|
return new SearchHitsImpl<>(hits.size(), TotalHitsRelation.EQUAL_TO, 0, Duration.ofMillis(1), scrollId, null, hits,
|
||||||
|
null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user