From 48d2cd146161d77baf9228d79d47003a1cad6aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gyula=20Cs=C3=B6r=C3=B6gi?= Date: Wed, 4 Sep 2019 22:20:04 +0200 Subject: [PATCH] DATAES-645 Fix missing highlight setting in scroll queries. Original PR: #312 --- .../core/ElasticsearchRestTemplate.java | 18 +++++ .../core/ElasticsearchTemplate.java | 18 +++++ .../core/ElasticsearchTemplateTests.java | 72 +++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index fb3c0977a..13dd48026 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -141,6 +141,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; * @author Farid Azaza * @author Peter-Josef Meisch * @author Mathias Teier + * @author Gyula Attila Csorogi */ public class ElasticsearchRestTemplate implements ElasticsearchOperations, EsClient, ApplicationContextAware { @@ -949,6 +950,23 @@ public class ElasticsearchRestTemplate prepareSort(query, searchSourceBuilder, entity); } + if (query instanceof SearchQuery) { + SearchQuery searchQuery = (SearchQuery) query; + + if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { + HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); + if (highlightBuilder == null) { + highlightBuilder = new HighlightBuilder(); + } + if (searchQuery.getHighlightFields() != null) { + for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { + highlightBuilder.field(highlightField); + } + } + searchSourceBuilder.highlighter(highlightBuilder); + } + } + request.source(searchSourceBuilder); return request; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 7ec417717..ae7ca3ced 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -122,6 +122,7 @@ import org.springframework.util.StringUtils; * @author Peter-Josef Meisch * @author Martin Choraine * @author Farid Azaza + * @author Gyula Attila Csorogi */ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient, ApplicationContextAware { @@ -808,6 +809,23 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient< prepareSort(query, requestBuilder, entity); } + if (query instanceof SearchQuery) { + SearchQuery searchQuery = (SearchQuery) query; + + if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { + HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); + if (highlightBuilder == null) { + highlightBuilder = new HighlightBuilder(); + } + if (searchQuery.getHighlightFields() != null) { + for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { + highlightBuilder.field(highlightField); + } + } + requestBuilder.highlighter(highlightBuilder); + } + } + return requestBuilder; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 4f24190cb..87c4d2054 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -27,6 +27,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import java.io.IOException; import java.lang.Double; import java.lang.Integer; import java.lang.Long; @@ -81,6 +82,7 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.util.CloseableIterator; import org.springframework.test.context.ContextConfiguration; @@ -107,6 +109,7 @@ import org.springframework.test.context.junit4.SpringRunner; * @author Peter-Josef Meisch * @author Martin Choraine * @author Farid Azaza + * @author Gyula Attila Csorogi */ @RunWith(SpringRunner.class) @ContextConfiguration("classpath:elasticsearch-template-test.xml") @@ -1589,6 +1592,75 @@ public class ElasticsearchTemplateTests { }); } + @Test // DATAES-645 + public void shouldReturnHighlightedFieldsInScroll() { + + // given + long scrollTimeInMillis = 3000; + String documentId = randomNumeric(5); + String actualType = "some test type"; + String actualMessage = "some test message"; + String highlightedType = "some test type"; + String highlightedMessage = "some test message"; + + SampleEntity sampleEntity = SampleEntity.builder().id(documentId).type(actualType).message(actualMessage) + .version(System.currentTimeMillis()).build(); + + IndexQuery indexQuery = getIndexQuery(sampleEntity); + + elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.refresh(SampleEntity.class); + + HighlightBuilder highlightBuilder = new HighlightBuilder().field("type").field("message"); + + SearchQuery searchQuery = new NativeSearchQueryBuilder() + .withQuery(boolQuery().must(termQuery("type", "test")).must(termQuery("message", "test"))) + .withPageable(PageRequest.of(0, 10)) + .withHighlightBuilder(highlightBuilder).build(); + + SearchResultMapper searchResultMapper = new SearchResultMapper() { + @Override + public AggregatedPage mapResults(SearchResponse response, Class clazz, Pageable pageable) { + DefaultEntityMapper defaultEntityMapper = new DefaultEntityMapper(new SimpleElasticsearchMappingContext()); + ArrayList result = new ArrayList<>(); + + for (SearchHit searchHit : response.getHits()) { + try { + result.add((T) defaultEntityMapper.mapToObject(searchHit.getSourceAsString(), SampleEntity.class)); + } catch (IOException e) { + e.printStackTrace(); + } + + Map highlightFields = searchHit.getHighlightFields(); + HighlightField highlightFieldType = highlightFields.get("type"); + HighlightField highlightFieldMessage = highlightFields.get("message"); + + // then + assertThat(highlightFieldType).isNotNull(); + assertThat(highlightFieldMessage).isNotNull(); + assertThat(highlightFieldType.fragments()[0].toString()).isEqualTo(highlightedType); + assertThat(highlightFieldMessage.fragments()[0].toString()).isEqualTo(highlightedMessage); + } + + return new AggregatedPageImpl<>(result, pageable, response.getHits().getTotalHits(), response.getAggregations(), + response.getScrollId(), response.getHits().getMaxScore()); + } + + @Override + public T mapSearchHit(SearchHit searchHit, Class type) { + return null; + } + }; + + // when + ScrolledPage scroll = elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery, SampleEntity.class, searchResultMapper); + while (scroll.hasContent()) { + scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class, searchResultMapper); + } + + elasticsearchTemplate.clearScroll(scroll.getScrollId()); + } + @Test // DATAES-479 public void shouldHonorTheHighlightBuilderOptions() {