mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-06 18:52:11 +00:00
DATAES-17 : Add support to retrieve highlighted text in search result
This commit is contained in:
parent
096c2e197e
commit
99a30a2a4b
@ -40,6 +40,7 @@ import org.elasticsearch.index.query.QueryBuilder;
|
|||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.search.facet.Facet;
|
import org.elasticsearch.search.facet.Facet;
|
||||||
import org.elasticsearch.search.facet.FacetBuilder;
|
import org.elasticsearch.search.facet.FacetBuilder;
|
||||||
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@ -388,6 +389,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(searchQuery.getHighlightFields() != null) {
|
||||||
|
for(HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()){
|
||||||
|
searchRequest.addHighlightedField(highlightField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return searchRequest.setQuery(searchQuery.getQuery()).execute().actionGet();
|
return searchRequest.setQuery(searchQuery.getQuery()).execute().actionGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ package org.springframework.data.elasticsearch.core.query;
|
|||||||
|
|
||||||
import org.elasticsearch.index.query.FilterBuilder;
|
import org.elasticsearch.index.query.FilterBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.facet.FacetBuilder;
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilder;
|
import org.elasticsearch.search.sort.SortBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
|||||||
private FilterBuilder filter;
|
private FilterBuilder filter;
|
||||||
private SortBuilder sort;
|
private SortBuilder sort;
|
||||||
private List<FacetRequest> facets;
|
private List<FacetRequest> facets;
|
||||||
|
private HighlightBuilder.Field[] highlightFields;
|
||||||
|
|
||||||
|
|
||||||
public NativeSearchQuery(QueryBuilder query) {
|
public NativeSearchQuery(QueryBuilder query) {
|
||||||
@ -54,6 +55,13 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
|||||||
this.sort = sort;
|
this.sort = sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NativeSearchQuery(QueryBuilder query, FilterBuilder filter, SortBuilder sort, HighlightBuilder.Field[] highlightFields) {
|
||||||
|
this.query = query;
|
||||||
|
this.filter = filter;
|
||||||
|
this.sort = sort;
|
||||||
|
this.highlightFields = highlightFields;
|
||||||
|
}
|
||||||
|
|
||||||
public QueryBuilder getQuery() {
|
public QueryBuilder getQuery() {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
@ -64,6 +72,11 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
|||||||
|
|
||||||
public SortBuilder getElasticsearchSort() {
|
public SortBuilder getElasticsearchSort() {
|
||||||
return sort;
|
return sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HighlightBuilder.Field[] getHighlightFields() {
|
||||||
|
return highlightFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFacet(FacetRequest facetRequest){
|
public void addFacet(FacetRequest facetRequest){
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core.query;
|
|||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.elasticsearch.index.query.FilterBuilder;
|
import org.elasticsearch.index.query.FilterBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilder;
|
import org.elasticsearch.search.sort.SortBuilder;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||||
@ -39,6 +40,7 @@ public class NativeSearchQueryBuilder {
|
|||||||
private FilterBuilder filterBuilder;
|
private FilterBuilder filterBuilder;
|
||||||
private SortBuilder sortBuilder;
|
private SortBuilder sortBuilder;
|
||||||
private List<FacetRequest> facetRequests = new ArrayList<FacetRequest>();
|
private List<FacetRequest> facetRequests = new ArrayList<FacetRequest>();
|
||||||
|
private HighlightBuilder.Field[] highlightFields;
|
||||||
private Pageable pageable;
|
private Pageable pageable;
|
||||||
private String[] indices;
|
private String[] indices;
|
||||||
private String[] types;
|
private String[] types;
|
||||||
@ -64,6 +66,11 @@ public class NativeSearchQueryBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NativeSearchQueryBuilder withHighlightFields(HighlightBuilder.Field... highlightFields){
|
||||||
|
this.highlightFields = highlightFields;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public NativeSearchQueryBuilder withPageable(Pageable pageable) {
|
public NativeSearchQueryBuilder withPageable(Pageable pageable) {
|
||||||
this.pageable = pageable;
|
this.pageable = pageable;
|
||||||
return this;
|
return this;
|
||||||
@ -85,7 +92,7 @@ public class NativeSearchQueryBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NativeSearchQuery build() {
|
public NativeSearchQuery build() {
|
||||||
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryBuilder, filterBuilder, sortBuilder);
|
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryBuilder, filterBuilder, sortBuilder, highlightFields);
|
||||||
if (pageable != null) {
|
if (pageable != null) {
|
||||||
nativeSearchQuery.setPageable(pageable);
|
nativeSearchQuery.setPageable(pageable);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ package org.springframework.data.elasticsearch.core.query;
|
|||||||
|
|
||||||
import org.elasticsearch.index.query.FilterBuilder;
|
import org.elasticsearch.index.query.FilterBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.facet.FacetBuilder;
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilder;
|
import org.elasticsearch.search.sort.SortBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||||
|
|
||||||
@ -38,4 +38,6 @@ public interface SearchQuery extends Query {
|
|||||||
SortBuilder getElasticsearchSort();
|
SortBuilder getElasticsearchSort();
|
||||||
|
|
||||||
List<FacetRequest> getFacets();
|
List<FacetRequest> getFacets();
|
||||||
|
|
||||||
|
HighlightBuilder.Field[] getHighlightFields();
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ public class SampleEntity {
|
|||||||
private String message;
|
private String message;
|
||||||
private int rate;
|
private int rate;
|
||||||
private boolean available;
|
private boolean available;
|
||||||
|
private String highlightedMessage;
|
||||||
@Version
|
@Version
|
||||||
private Long version;
|
private Long version;
|
||||||
|
|
||||||
@ -77,6 +78,14 @@ public class SampleEntity {
|
|||||||
this.available = available;
|
this.available = available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHighlightedMessage() {
|
||||||
|
return highlightedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHighlightedMessage(String highlightedMessage) {
|
||||||
|
this.highlightedMessage = highlightedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getVersion() {
|
public Long getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import org.elasticsearch.action.index.IndexRequest;
|
|||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.index.engine.DocumentMissingException;
|
import org.elasticsearch.index.engine.DocumentMissingException;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -27,7 +28,6 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.elasticsearch.SampleEntity;
|
import org.springframework.data.elasticsearch.SampleEntity;
|
||||||
@ -44,6 +44,7 @@ import static org.elasticsearch.index.query.FilterBuilders.boolFilter;
|
|||||||
import static org.elasticsearch.index.query.FilterBuilders.termFilter;
|
import static org.elasticsearch.index.query.FilterBuilders.termFilter;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.fieldQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.fieldQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||||
|
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
@ -778,4 +779,54 @@ public class ElasticsearchTemplateTests {
|
|||||||
assertThat(indexedEntity.getMessage(), is(message));
|
assertThat(indexedEntity.getMessage(), is(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnHighlightedFieldsForGivenQueryAndFields(){
|
||||||
|
|
||||||
|
//given
|
||||||
|
String documentId = randomNumeric(5);
|
||||||
|
String actualMessage = "some test message";
|
||||||
|
String highlightedMessage = "some <em>test</em> message";
|
||||||
|
|
||||||
|
SampleEntity sampleEntity = new SampleEntity();
|
||||||
|
sampleEntity.setId(documentId);
|
||||||
|
sampleEntity.setMessage(actualMessage);
|
||||||
|
sampleEntity.setVersion(System.currentTimeMillis());
|
||||||
|
|
||||||
|
IndexQuery indexQuery = new IndexQuery();
|
||||||
|
indexQuery.setId(documentId);
|
||||||
|
indexQuery.setObject(sampleEntity);
|
||||||
|
|
||||||
|
elasticsearchTemplate.index(indexQuery);
|
||||||
|
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||||
|
|
||||||
|
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||||
|
.withQuery(termQuery("message", "test"))
|
||||||
|
.withHighlightFields(new HighlightBuilder.Field("message"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, new ResultsMapper<SampleEntity>() {
|
||||||
|
@Override
|
||||||
|
public FacetedPage<SampleEntity> mapResults(SearchResponse response) {
|
||||||
|
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
|
||||||
|
for (SearchHit searchHit : response.getHits()) {
|
||||||
|
if (response.getHits().getHits().length <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
SampleEntity user = new SampleEntity();
|
||||||
|
user.setId(searchHit.getId());
|
||||||
|
user.setMessage((String) searchHit.getSource().get("message"));
|
||||||
|
user.setHighlightedMessage(searchHit.getHighlightFields().get("message").fragments()[0].toString());
|
||||||
|
chunk.add(user);
|
||||||
|
}
|
||||||
|
if(chunk.size() > 0){
|
||||||
|
return new FacetedPageImpl<SampleEntity>(chunk);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assertThat(sampleEntities.getContent().get(0).getHighlightedMessage(), is(highlightedMessage));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user