ElasticSearch如何设置返回结果关键词高亮显示

本文转自本人博客:https://funyan.cn/p/6364.html

前言

类似于百度等搜索引擎,我们的搜索词都会在搜索结果中显示红色或其他高亮颜色,这就叫高亮显示,ElasticSearch同样也是支持这个功能的,下面我们就看一下如何用es实现搜索结果的高亮显示

 

教程

1、重写高亮显示的mapper类

package cn.funyan.blog.es;

import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.bytes.ByteBufferReference;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.DefaultResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;

import java.nio.ByteBuffer;
import java.util.Map;

/**
 *高亮显示类
 **/
public class HighlightResultMapper extends DefaultResultMapper
{
	@Override
	public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
		for (SearchHit hit : response.getHits()) {
			Map<String, Object> sourceMap = hit.getSourceAsMap();
			for (Map.Entry<String, HighlightField> entry : hit.getHighlightFields().entrySet()) {
				String key = entry.getKey();
				if (sourceMap.containsKey(key)) {
					Text[] fragments = entry.getValue().getFragments();
					sourceMap.put(key, transTextArrayToString(fragments));
				}
			}
			hit.sourceRef(new ByteBufferReference(ByteBuffer.wrap(JSONObject.toJSONString(sourceMap).getBytes())));
		}
		return super.mapResults(response, clazz, pageable);
	}

	private String transTextArrayToString(Text[] fragments) {
		if (null == fragments) {
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		for (Text fragment : fragments) {
			buffer.append(fragment.string());
		}
		return buffer.toString();
	}
}

 

2、编写搜索方法

public List<Article> searchArtV2(Integer pageNum, String keywords) {
		if(StringUtils.isEmpty(keywords)){
			return new Res().failed().setMsg("搜索词不得为空");
		}
		//构建分页数据
		Pageable pageable=PageRequest.of(Page.getEsPageNum(pageNum),Page.DEFAULT_PAGESIZE);
		//构建条件查询器
		QueryStringQueryBuilder boolQueryBuilder = new QueryStringQueryBuilder(keywords);
		//构建条件
		boolQueryBuilder.field("head")
				.field("introduce");
		//构建查询器
                //高亮的前缀和后缀,这里可以自定义,只要可以高亮显示
		String preTag = "<em>";
		String postTag = "</em>";
		NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
				.withQuery(boolQueryBuilder)
				.withFields("id","head","titlePhoto","pageView","createdAt","description","introduce","classifyName")
                                //重点!!!这里支持检索的字段高亮,显示高亮的必须是你检索的字段
				.withHighlightFields(new HighlightBuilder.Field("head").preTags(preTag).postTags(postTag),new HighlightBuilder.Field("introduce").preTags(preTag).postTags(postTag))
				.withPageable(pageable)
				.build();
                //这里直接传入我们写的高亮类
		AggregatedPage<Article> articles = elasticsearchRestTemplate.queryForPage(searchQuery, Article.class, new HighlightResultMapper());
		List<Article> list=articles.getContent();
		log.info("用户搜索文章:{}",JSONObject.toJSON(result));
		return list;
	}

 

3、这样就可以看到我们的搜索词都加上了<em></em>标签,效果如下

本文转自本人博客:https://funyan.cn/p/6364.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值