Skip to content

Commit 99a30a2

Browse files
committed
DATAES-17 : Add support to retrieve highlighted text in search result
1 parent 096c2e1 commit 99a30a2

File tree

6 files changed

+93
-4
lines changed

6 files changed

+93
-4
lines changed

src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.elasticsearch.search.SearchHit;
4141
import org.elasticsearch.search.facet.Facet;
4242
import org.elasticsearch.search.facet.FacetBuilder;
43+
import org.elasticsearch.search.highlight.HighlightBuilder;
4344
import org.elasticsearch.search.sort.SortOrder;
4445
import org.springframework.data.domain.Page;
4546
import org.springframework.data.domain.Pageable;
@@ -388,6 +389,12 @@ private SearchResponse doSearch(SearchRequestBuilder searchRequest, SearchQuery
388389
}
389390
}
390391

392+
if(searchQuery.getHighlightFields() != null) {
393+
for(HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()){
394+
searchRequest.addHighlightedField(highlightField);
395+
}
396+
}
397+
391398
return searchRequest.setQuery(searchQuery.getQuery()).execute().actionGet();
392399
}
393400

src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import org.elasticsearch.index.query.FilterBuilder;
1919
import org.elasticsearch.index.query.QueryBuilder;
20-
import org.elasticsearch.search.facet.FacetBuilder;
20+
import org.elasticsearch.search.highlight.HighlightBuilder;
2121
import org.elasticsearch.search.sort.SortBuilder;
2222
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
2323

@@ -37,6 +37,7 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
3737
private FilterBuilder filter;
3838
private SortBuilder sort;
3939
private List<FacetRequest> facets;
40+
private HighlightBuilder.Field[] highlightFields;
4041

4142

4243
public NativeSearchQuery(QueryBuilder query) {
@@ -54,6 +55,13 @@ public NativeSearchQuery(QueryBuilder query, FilterBuilder filter, SortBuilder s
5455
this.sort = sort;
5556
}
5657

58+
public NativeSearchQuery(QueryBuilder query, FilterBuilder filter, SortBuilder sort, HighlightBuilder.Field[] highlightFields) {
59+
this.query = query;
60+
this.filter = filter;
61+
this.sort = sort;
62+
this.highlightFields = highlightFields;
63+
}
64+
5765
public QueryBuilder getQuery() {
5866
return query;
5967
}
@@ -64,6 +72,11 @@ public FilterBuilder getFilter() {
6472

6573
public SortBuilder getElasticsearchSort() {
6674
return sort;
75+
}
76+
77+
@Override
78+
public HighlightBuilder.Field[] getHighlightFields() {
79+
return highlightFields;
6780
}
6881

6982
public void addFacet(FacetRequest facetRequest){

src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.apache.commons.collections.CollectionUtils;
1919
import org.elasticsearch.index.query.FilterBuilder;
2020
import org.elasticsearch.index.query.QueryBuilder;
21+
import org.elasticsearch.search.highlight.HighlightBuilder;
2122
import org.elasticsearch.search.sort.SortBuilder;
2223
import org.springframework.data.domain.Pageable;
2324
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
@@ -39,6 +40,7 @@ public class NativeSearchQueryBuilder {
3940
private FilterBuilder filterBuilder;
4041
private SortBuilder sortBuilder;
4142
private List<FacetRequest> facetRequests = new ArrayList<FacetRequest>();
43+
private HighlightBuilder.Field[] highlightFields;
4244
private Pageable pageable;
4345
private String[] indices;
4446
private String[] types;
@@ -64,6 +66,11 @@ public NativeSearchQueryBuilder withFacet(FacetRequest facetRequest) {
6466
return this;
6567
}
6668

69+
public NativeSearchQueryBuilder withHighlightFields(HighlightBuilder.Field... highlightFields){
70+
this.highlightFields = highlightFields;
71+
return this;
72+
}
73+
6774
public NativeSearchQueryBuilder withPageable(Pageable pageable) {
6875
this.pageable = pageable;
6976
return this;
@@ -85,7 +92,7 @@ public NativeSearchQueryBuilder withFields(String... fields) {
8592
}
8693

8794
public NativeSearchQuery build() {
88-
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryBuilder, filterBuilder, sortBuilder);
95+
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryBuilder, filterBuilder, sortBuilder, highlightFields);
8996
if (pageable != null) {
9097
nativeSearchQuery.setPageable(pageable);
9198
}

src/main/java/org/springframework/data/elasticsearch/core/query/SearchQuery.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import org.elasticsearch.index.query.FilterBuilder;
1919
import org.elasticsearch.index.query.QueryBuilder;
20-
import org.elasticsearch.search.facet.FacetBuilder;
20+
import org.elasticsearch.search.highlight.HighlightBuilder;
2121
import org.elasticsearch.search.sort.SortBuilder;
2222
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
2323

@@ -38,4 +38,6 @@ public interface SearchQuery extends Query {
3838
SortBuilder getElasticsearchSort();
3939

4040
List<FacetRequest> getFacets();
41+
42+
HighlightBuilder.Field[] getHighlightFields();
4143
}

src/test/java/org/springframework/data/elasticsearch/SampleEntity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class SampleEntity {
3434
private String message;
3535
private int rate;
3636
private boolean available;
37+
private String highlightedMessage;
3738
@Version
3839
private Long version;
3940

@@ -77,6 +78,14 @@ public void setAvailable(boolean available) {
7778
this.available = available;
7879
}
7980

81+
public String getHighlightedMessage() {
82+
return highlightedMessage;
83+
}
84+
85+
public void setHighlightedMessage(String highlightedMessage) {
86+
this.highlightedMessage = highlightedMessage;
87+
}
88+
8089
public Long getVersion() {
8190
return version;
8291
}

src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.elasticsearch.action.search.SearchResponse;
2020
import org.elasticsearch.index.engine.DocumentMissingException;
2121
import org.elasticsearch.search.SearchHit;
22+
import org.elasticsearch.search.highlight.HighlightBuilder;
2223
import org.elasticsearch.search.sort.FieldSortBuilder;
2324
import org.elasticsearch.search.sort.SortOrder;
2425
import org.junit.Before;
@@ -27,7 +28,6 @@
2728
import org.junit.runner.RunWith;
2829
import org.springframework.beans.factory.annotation.Autowired;
2930
import org.springframework.data.domain.Page;
30-
import org.springframework.data.domain.PageImpl;
3131
import org.springframework.data.domain.PageRequest;
3232
import org.springframework.data.domain.Sort;
3333
import org.springframework.data.elasticsearch.SampleEntity;
@@ -44,6 +44,7 @@
4444
import static org.elasticsearch.index.query.FilterBuilders.termFilter;
4545
import static org.elasticsearch.index.query.QueryBuilders.fieldQuery;
4646
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
47+
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
4748
import static org.hamcrest.Matchers.*;
4849
import static org.junit.Assert.*;
4950

@@ -778,4 +779,54 @@ public void shouldDoUpsertIfDocumentDoesNotExist(){
778779
assertThat(indexedEntity.getMessage(), is(message));
779780
}
780781

782+
@Test
783+
public void shouldReturnHighlightedFieldsForGivenQueryAndFields(){
784+
785+
//given
786+
String documentId = randomNumeric(5);
787+
String actualMessage = "some test message";
788+
String highlightedMessage = "some <em>test</em> message";
789+
790+
SampleEntity sampleEntity = new SampleEntity();
791+
sampleEntity.setId(documentId);
792+
sampleEntity.setMessage(actualMessage);
793+
sampleEntity.setVersion(System.currentTimeMillis());
794+
795+
IndexQuery indexQuery = new IndexQuery();
796+
indexQuery.setId(documentId);
797+
indexQuery.setObject(sampleEntity);
798+
799+
elasticsearchTemplate.index(indexQuery);
800+
elasticsearchTemplate.refresh(SampleEntity.class, true);
801+
802+
SearchQuery searchQuery = new NativeSearchQueryBuilder()
803+
.withQuery(termQuery("message", "test"))
804+
.withHighlightFields(new HighlightBuilder.Field("message"))
805+
.build();
806+
807+
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, new ResultsMapper<SampleEntity>() {
808+
@Override
809+
public FacetedPage<SampleEntity> mapResults(SearchResponse response) {
810+
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
811+
for (SearchHit searchHit : response.getHits()) {
812+
if (response.getHits().getHits().length <= 0) {
813+
return null;
814+
}
815+
SampleEntity user = new SampleEntity();
816+
user.setId(searchHit.getId());
817+
user.setMessage((String) searchHit.getSource().get("message"));
818+
user.setHighlightedMessage(searchHit.getHighlightFields().get("message").fragments()[0].toString());
819+
chunk.add(user);
820+
}
821+
if(chunk.size() > 0){
822+
return new FacetedPageImpl<SampleEntity>(chunk);
823+
}
824+
return null;
825+
}
826+
});
827+
828+
assertThat(sampleEntities.getContent().get(0).getHighlightedMessage(), is(highlightedMessage));
829+
830+
}
831+
781832
}

0 commit comments

Comments
 (0)