mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-23 12:32:10 +00:00
DATAES-722 - Return total count relation in the SearchHits object.
Original PR: #369
This commit is contained in:
parent
90d29994f1
commit
5c862e80bf
@ -39,38 +39,50 @@ public class SearchHits<T> implements Streamable<SearchHit<T>> {
|
||||
private final String scrollId;
|
||||
private final List<? extends SearchHit<T>> searchHits;
|
||||
private final Aggregations aggregations;
|
||||
private final TotalHitsRelation totalHitsRelation;
|
||||
|
||||
/**
|
||||
* @param totalHits
|
||||
* @param maxScore
|
||||
* @param totalHits the number of total hits for the search
|
||||
* @param totalHitsRelation the relation {@see TotalHitsRelation}, must not be {@literal null}
|
||||
* @param maxScore the maximum score
|
||||
* @param scrollId the scroll id if available
|
||||
* @param searchHits must not be {@literal null}
|
||||
* @param aggregations
|
||||
* @param aggregations the aggregations if available
|
||||
*/
|
||||
public SearchHits(long totalHits, float maxScore, @Nullable String scrollId, List<? extends SearchHit<T>> searchHits,
|
||||
@Nullable Aggregations aggregations) {
|
||||
public SearchHits(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, @Nullable String scrollId,
|
||||
List<? extends SearchHit<T>> searchHits, @Nullable Aggregations aggregations) {
|
||||
|
||||
Assert.notNull(searchHits, "searchHits must not be null");
|
||||
|
||||
this.totalHits = totalHits;
|
||||
this.totalHitsRelation = totalHitsRelation;
|
||||
this.maxScore = maxScore;
|
||||
this.scrollId = scrollId;
|
||||
this.searchHits = searchHits;
|
||||
this.aggregations = aggregations;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterator<SearchHit<T>> iterator() {
|
||||
return (Iterator<SearchHit<T>>) searchHits.iterator();
|
||||
}
|
||||
|
||||
// region getter
|
||||
/**
|
||||
* @return the number of total hits.
|
||||
*/
|
||||
// region getter
|
||||
public long getTotalHits() {
|
||||
return totalHits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the relation for the total hits
|
||||
*/
|
||||
public TotalHitsRelation getTotalHitsRelation() {
|
||||
return totalHitsRelation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum score
|
||||
*/
|
||||
@ -107,19 +119,20 @@ public class SearchHits<T> implements Streamable<SearchHit<T>> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SearchHits{" +
|
||||
"totalHits=" + totalHits +
|
||||
", maxScore=" + maxScore +
|
||||
", scrollId='" + scrollId + '\'' +
|
||||
", searchHits=" + StringUtils.collectionToCommaDelimitedString(searchHits) +
|
||||
", aggregations=" + aggregations +
|
||||
return "SearchHits{" + //
|
||||
"totalHits=" + totalHits + //
|
||||
", totalHitsRelation=" + totalHitsRelation + //
|
||||
", maxScore=" + maxScore + //
|
||||
", scrollId='" + scrollId + '\'' + //
|
||||
", searchHits={" + searchHits.size() + " elements}" + //
|
||||
", aggregations=" + aggregations + //
|
||||
'}';
|
||||
}
|
||||
|
||||
// region aggregations
|
||||
/**
|
||||
* @return true if aggregations are available
|
||||
*/
|
||||
// region aggregations
|
||||
public boolean hasAggregations() {
|
||||
return aggregations != null;
|
||||
}
|
||||
@ -133,4 +146,12 @@ public class SearchHits<T> implements Streamable<SearchHit<T>> {
|
||||
}
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* Enum to represent the relation that Elasticsearch returns for the totalHits value {@see <a href=
|
||||
* "https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-request-body.html#request-body-search-track-total-hits">Ekasticsearch
|
||||
* docs</a>}
|
||||
*/
|
||||
public enum TotalHitsRelation {
|
||||
EQUAL_TO, GREATER_THAN_OR_EQUAL_TO
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,10 @@ public class MappingElasticsearchConverter
|
||||
.map(searchDocument -> read(type, searchDocument)) //
|
||||
.collect(Collectors.toList());
|
||||
Aggregations aggregations = searchDocumentResponse.getAggregations();
|
||||
return new SearchHits<>(totalHits, maxScore, scrollId, searchHits, aggregations);
|
||||
SearchHits.TotalHitsRelation totalHitsRelation = SearchHits.TotalHitsRelation
|
||||
.valueOf(searchDocumentResponse.getTotalHitsRelation());
|
||||
|
||||
return new SearchHits<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,14 +20,14 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.apache.lucene.search.TotalHits;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.search.aggregations.Aggregations;
|
||||
import org.springframework.data.elasticsearch.support.SearchHitsUtil;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* This represents the complete search response from Elasticsearch, including the returned documents. Instances must be
|
||||
* created with the {@link #from(org.elasticsearch.action.search.SearchResponse)} method.
|
||||
* created with the {@link #from(SearchResponse)} method.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.0
|
||||
@ -35,14 +35,16 @@ import org.springframework.util.Assert;
|
||||
public class SearchDocumentResponse {
|
||||
|
||||
private long totalHits;
|
||||
private String totalHitsRelation;
|
||||
private float maxScore;
|
||||
private final String scrollId;
|
||||
private final List<SearchDocument> searchDocuments;
|
||||
private final Aggregations aggregations;
|
||||
|
||||
private SearchDocumentResponse(long totalHits, float maxScore, String scrollId, List<SearchDocument> searchDocuments,
|
||||
Aggregations aggregations) {
|
||||
private SearchDocumentResponse(long totalHits, String totalHitsRelation, float maxScore, String scrollId,
|
||||
List<SearchDocument> searchDocuments, Aggregations aggregations) {
|
||||
this.totalHits = totalHits;
|
||||
this.totalHitsRelation = totalHitsRelation;
|
||||
this.maxScore = maxScore;
|
||||
this.scrollId = scrollId;
|
||||
this.searchDocuments = searchDocuments;
|
||||
@ -53,6 +55,10 @@ public class SearchDocumentResponse {
|
||||
return totalHits;
|
||||
}
|
||||
|
||||
public String getTotalHitsRelation() {
|
||||
return totalHitsRelation;
|
||||
}
|
||||
|
||||
public float getMaxScore() {
|
||||
return maxScore;
|
||||
}
|
||||
@ -70,23 +76,29 @@ public class SearchDocumentResponse {
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a SearchDocumentResponse from the {@link org.elasticsearch.action.search.SearchResponse}
|
||||
* creates a SearchDocumentResponse from the {@link SearchResponse}
|
||||
*
|
||||
* @param searchResponse must not be {@literal null}
|
||||
* @return
|
||||
* @param searchResponse
|
||||
* must not be {@literal null}
|
||||
* @return the SearchDocumentResponse
|
||||
*/
|
||||
public static SearchDocumentResponse from(SearchResponse searchResponse) {
|
||||
Assert.notNull(searchResponse, "searchResponse must not be null");
|
||||
|
||||
long totalHits = SearchHitsUtil.getTotalCount(searchResponse.getHits());
|
||||
TotalHits responseTotalHits = searchResponse.getHits().getTotalHits();
|
||||
long totalHits = responseTotalHits.value;
|
||||
String totalHitsRelation = responseTotalHits.relation.name();
|
||||
|
||||
float maxScore = searchResponse.getHits().getMaxScore();
|
||||
String scrollId = searchResponse.getScrollId();
|
||||
|
||||
List<SearchDocument> searchDocuments = StreamSupport.stream(searchResponse.getHits().spliterator(), false) //
|
||||
.filter(Objects::nonNull) //
|
||||
.map(DocumentAdapters::from) //
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Aggregations aggregations = searchResponse.getAggregations();
|
||||
|
||||
return new SearchDocumentResponse(totalHits, maxScore, scrollId, searchDocuments, aggregations);
|
||||
return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, searchDocuments, aggregations);
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public abstract class ElasticsearchTemplateTests {
|
||||
assertThat(count).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // DATAES-722
|
||||
public void shouldReturnObjectForGivenId() {
|
||||
|
||||
// given
|
||||
@ -289,7 +289,8 @@ public abstract class ElasticsearchTemplateTests {
|
||||
|
||||
// then
|
||||
assertThat(searchHits).isNotNull();
|
||||
assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1);
|
||||
assertThat(searchHits.getTotalHits()).isEqualTo(1);
|
||||
assertThat(searchHits.getTotalHitsRelation()).isEqualByComparingTo(SearchHits.TotalHitsRelation.EQUAL_TO);
|
||||
}
|
||||
|
||||
@Test // DATAES-595
|
||||
|
Loading…
x
Reference in New Issue
Block a user