实现ElasticSearch 高亮搜索
实现高亮搜索,首先直接使用使用ElasticsearchRestTemplate
不在使用ElasticsearchRepository
@Autowired
ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
public void searchTest() {
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "felix");
Sort sort = Sort.by(Order.desc("id"));
SearchQuery searchQuery = new NativeSearchQueryBuilder()
//设置高亮字段
.withHighlightFields(new HighlightBuilder.Field("name")
.preTags("<span style='color:red'>")
.postTags("</span>"))
.withQuery(matchQueryBuilder)
//设置分页数据
.withPageable(PageRequest.of(0, 2, sort))
.build();
AggregatedPage<Article> articles = elasticsearchRestTemplate.queryForPage(searchQuery, Article.class, highlightResultHelper);
for (Article article : articles) {
System.out.println(article);
}
}
自定义 highlightResultHelper
为了实现高亮显示,需要 自定义一个SearchResultMapper
@Slf4j
@Component
public class HighlightResultHelper implements SearchResultMapper {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
List<T> results = new ArrayList<>();
for (SearchHit hit : response.getHits()) {
if (hit != null) {
T result = null;
if (StringUtils.hasText(hit.getSourceAsString())) {
result = JSONObject.parseObject(hit.getSourceAsString(), clazz);
}
// 高亮查询
for (HighlightField field : hit.getHighlightFields().values()) {
try {
PropertyUtils.setProperty(result, field.getName(), concat(field.fragments()));
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
log.error("设置高亮字段异常:{}", e.getMessage(), e);
}
}
results.add(result);
}
}
return new AggregatedPageImpl<T>(results, pageable, response.getHits().getTotalHits(), response.getAggregations(), response.getScrollId());
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> clazz) {
List<T> results = new ArrayList<>();
for (HighlightField field : searchHit.getHighlightFields().values()) {
T result = null;
if (StringUtils.hasText(searchHit.getSourceAsString())) {
result = JSONObject.parseObject(searchHit.getSourceAsString(), clazz);
}
try {
PropertyUtils.setProperty(result, field.getName(), concat(field.fragments()));
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
log.error("设置高亮字段异常:{}", e.getMessage(), e);
}
results.add(result);
}
return null;
}
private String concat(Text[] texts) {
StringBuffer sb = new StringBuffer();
for (Text text : texts) {
sb.append(text.toString());
}
return sb.toString();
}
}
这里应用了fastjson解析成实体bean,和PropertyUtils用于设置高亮字段
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
</dependency>
结果
name 已添加 自定义高亮字
Article(id=9, title=Elasticsearch入门(9), name=<span style='color:red'>felix</span>, createDateTime=Tue Nov 12 16:30:42 CST 2019)
Article(id=8, title=Elasticsearch入门(8), name=<span style='color:red'>felix</span>, createDateTime=Tue Nov 12 16:30:42 CST 2019)