DATAES-952 - Optimize SearchPage implementation.

Original PR: #539
This commit is contained in:
Peter-Josef Meisch 2020-10-16 16:24:59 +02:00 committed by GitHub
parent 9bc4bee86f
commit 23ac6d77cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 4 deletions

View File

@ -158,5 +158,13 @@ public final class SearchHitSupport {
public SearchHits<T> getSearchHits() { public SearchHits<T> getSearchHits() {
return searchHits; return searchHits;
} }
/*
* return the same instance as in getSearchHits().getSearchHits()
*/
@Override
public List<SearchHit<T>> getContent() {
return searchHits.getSearchHits();
}
} }
} }

View File

@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.util.Lazy;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -35,9 +36,10 @@ 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 String scrollId; @Nullable private final String scrollId;
private final List<? extends SearchHit<T>> searchHits; private final List<? extends SearchHit<T>> searchHits;
private final Aggregations aggregations; private final Lazy<List<SearchHit<T>>> unmodifiableSearchHits;
@Nullable private final Aggregations aggregations;
/** /**
* @param totalHits the number of total hits for the search * @param totalHits the number of total hits for the search
@ -58,6 +60,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
this.scrollId = scrollId; this.scrollId = scrollId;
this.searchHits = searchHits; this.searchHits = searchHits;
this.aggregations = aggregations; this.aggregations = aggregations;
this.unmodifiableSearchHits = Lazy.of(() -> Collections.unmodifiableList(searchHits));
} }
// region getter // region getter
@ -84,7 +87,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
@Override @Override
public List<SearchHit<T>> getSearchHits() { public List<SearchHit<T>> getSearchHits() {
return Collections.unmodifiableList(searchHits); return unmodifiableSearchHits.get();
} }
// endregion // endregion

View File

@ -15,12 +15,15 @@
*/ */
package org.springframework.data.elasticsearch.core; package org.springframework.data.elasticsearch.core;
import org.springframework.lang.Nullable;
/** /**
* This interface is used to expose the current {@code scrollId} from the underlying scroll context. * This interface is used to expose the current {@code scrollId} from the underlying scroll context.
* <p> * <p>
* Internal use only. * Internal use only.
* *
* @author Sascha Woo * @author Sascha Woo
* @author Peter-Josef Meisch
* @param <T> * @param <T>
* @since 4.0 * @since 4.0
*/ */
@ -29,6 +32,7 @@ public interface SearchScrollHits<T> extends SearchHits<T> {
/** /**
* @return the scroll id * @return the scroll id
*/ */
@Nullable
String getScrollId(); String getScrollId();
} }

View File

@ -19,17 +19,23 @@ 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.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.Aggregations;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.CloseableIterator;
/** /**
* @author Roman Puchkovskiy * @author Roman Puchkovskiy
* @author Peter-Josef Meisch
*/ */
class SearchHitSupportTest { class SearchHitSupportTest {
@Test // DATAES-772 @Test // DATAES-772
void unwrapsSearchHitsIteratorToCloseableIteratorOfEntities() { void unwrapsSearchHitsIteratorToCloseableIteratorOfEntities() {
TestStringSearchHitsIterator searchHitsIterator = new TestStringSearchHitsIterator(); TestStringSearchHitsIterator searchHitsIterator = new TestStringSearchHitsIterator();
@ -38,6 +44,7 @@ class SearchHitSupportTest {
CloseableIterator<String> unwrappedIterator = (CloseableIterator<String>) SearchHitSupport CloseableIterator<String> unwrappedIterator = (CloseableIterator<String>) SearchHitSupport
.unwrapSearchHits(searchHitsIterator); .unwrapSearchHits(searchHitsIterator);
// noinspection ConstantConditions
assertThat(unwrappedIterator.next()).isEqualTo("one"); assertThat(unwrappedIterator.next()).isEqualTo("one");
assertThat(unwrappedIterator.next()).isEqualTo("two"); assertThat(unwrappedIterator.next()).isEqualTo("two");
assertThat(unwrappedIterator.hasNext()).isFalse(); assertThat(unwrappedIterator.hasNext()).isFalse();
@ -47,6 +54,27 @@ class SearchHitSupportTest {
assertThat(searchHitsIterator.closed).isTrue(); assertThat(searchHitsIterator.closed).isTrue();
} }
@Test // DATAES-952
@DisplayName("should return the same list instance in SearchHits and getContent")
void shouldReturnTheSameListInstanceInSearchHitsAndGetContent() {
List<SearchHit<String>> hits = new ArrayList<>();
hits.add(new SearchHit<>(null, null, 0, null, null, "one"));
hits.add(new SearchHit<>(null, null, 0, null, null, "two"));
hits.add(new SearchHit<>(null, null, 0, null, null, "three"));
hits.add(new SearchHit<>(null, null, 0, null, null, "four"));
hits.add(new SearchHit<>(null, null, 0, null, null, "five"));
SearchHits<String> originalSearchHits = new SearchHitsImpl<>(hits.size(), TotalHitsRelation.EQUAL_TO, 0, "scroll",
hits, null);
SearchPage<String> searchPage = SearchHitSupport.searchPageFor(originalSearchHits, PageRequest.of(0, 3));
SearchHits<String> searchHits = searchPage.getSearchHits();
assertThat(searchHits).isEqualTo(originalSearchHits);
assertThat(searchHits.getSearchHits()).isSameAs(searchPage.getContent());
}
private static class TestStringSearchHitsIterator implements SearchHitsIterator<String> { private static class TestStringSearchHitsIterator implements SearchHitsIterator<String> {
private final Iterator<String> iterator = Arrays.asList("one", "two").iterator(); private final Iterator<String> iterator = Arrays.asList("one", "two").iterator();
private boolean closed = false; private boolean closed = false;
@ -87,4 +115,5 @@ class SearchHitSupportTest {
return new SearchHit<>("index", "id", 1.0f, new Object[0], emptyMap(), nextString); return new SearchHit<>("index", "id", 1.0f, new Object[0], emptyMap(), nextString);
} }
} }
} }