如何通过Elasticsearch实现搜索的关键词达到高亮的效果

高亮

首先介绍一下什么是搜索的关键词达到高亮的效果,如图所示
在这里插入图片描述
当在百度里面搜索elasticsearch的时候,可以看到出现的搜索结果里面elasticsearch这个关键词明显与其他的条文不一样,用红颜色凸显了“高亮效果”。当我们想要在自己的项目里面也实现相同的高亮效果,可以借助ES来帮助我们实现。

通过ES实现高亮效果

现在有一个场景:输入相关的面试题题目返回的结果中题目出现高亮效果,类似这样的效果
在这里插入图片描述
那么后端的逻辑应该怎么写呢?(只说明核心逻辑)

首先在查询ES的时候就设置好相应的高亮属性

    private EsSearchRequest createSearchListQuery(SubjectInfoES req){
        EsSearchRequest esSearchRequest = new EsSearchRequest();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
		
		//构造查询条件-根据题目名字查询
        MatchQueryBuilder matchNameQueryBuilder =
                QueryBuilders.matchQuery(EsSubjectFields.SUBJECT_NAME,req.getSubjectName());
        boolQueryBuilder.should(matchNameQueryBuilder);
        //设置优先级
        matchNameQueryBuilder.boost(2);

		//其他的代码逻辑...

        //设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("+").requireFieldMatch(false);
        highlightBuilder.preTags("<span style = \"color:red\">");
        highlightBuilder.postTags("</span>");

        //设置高亮和条件
        esSearchRequest.setHighlightBuilder(highlightBuilder);
        esSearchRequest.setBoolQueryBuilder(boolQueryBuilder);
		
		//其他的代码逻辑...

        return esSearchRequest;
    }

这里通过
HighlightBuilder highlightBuilder = new HighlightBuilder().field("+").requireFieldMatch(false);
构造了一个ES的高亮器
在这里,field("+") 表示要对所有字段进行高亮处理
requireFieldMatch(false) 表示不需要确切字段匹配,即如果任何字段中包含查询的关键字,都会被高亮显示
如果设置为requireFieldMatch(true)的话 即查询出来的字段中要完全包含查询的关键字才会被高亮处理

        highlightBuilder.preTags("<span style = \"color:red\">");
        highlightBuilder.postTags("</span>");

这两段代码的意思是要实现高亮的字段在返回给前端的时候会被"<span style = \"color:red\">""</span>"囊括起来,举个例子:<span style = \"color:red\"> elasticsearch倒排索引为什么快 </span>

        //设置高亮和条件
        esSearchRequest.setHighlightBuilder(highlightBuilder);
        esSearchRequest.setBoolQueryBuilder(boolQueryBuilder);

这两段代码的作用是设置搜索关键词实现高亮和实现高亮的关键词是哪些关键词

在设置好高亮的相关条件以后,就得从ES中查询相关的数据了并且处理相关的数据

    public PageResult<SubjectInfoES> querySubjectList(SubjectInfoES req) {
		PageResult<SubjectInfoES> pageResult = new PageResult<>();
		//设置相关条件
        EsSearchRequest esSearchRequest = createSearchListQuery(req);
        //搜索
        SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(),esSearchRequest);

        //获取Elasticsearch搜索响应中包含的搜索结果
        SearchHits searchHits = searchResponse.getHits();
        SearchHit[] hits = searchHits.getHits();
        //遍历响应结果
        for (SearchHit hit : hits) {
            //将ES返回的结果映射到返回的实体中的代码....
			
			//开始处理高亮
			
			//高亮的字段
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();

        //处理name的高亮字段
        HighlightField nameHighlightField = highlightFields.get(EsSubjectFields.SUBJECT_NAME);
        if (ObjectUtils.isNotEmpty(nameHighlightField)){
            Text[] fragments = nameHighlightField.fragments();
            StringBuilder stringBuilder = new StringBuilder();
            for (Text fragment : fragments){
                stringBuilder.append(fragment.string());
            }
            result.setSubjectName(stringBuilder.toString());
        }
        //处理内容中的高亮字段
        HighlightField answerHighlightField = highlightFields.get(EsSubjectFields.SUBJECT_ANSWER);
        if (ObjectUtils.isNotEmpty(answerHighlightField)){
            Text[] fragments = answerHighlightField.fragments();
            StringBuilder stringBuilder = new StringBuilder();
            for (Text fragment : fragments){
                stringBuilder.append(fragment.string());
            }
            result.setSubjectAnswer(stringBuilder.toString());
        }
            
            //将ES返回的结果映射到返回的实体中的代码....
        }

		//其他的代码逻辑

        return pageResult;
    }

这段代码展现了如何处理高亮,核心代码实际上是这一段

        //高亮的字段
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();

        //处理name的高亮字段
        HighlightField nameHighlightField = highlightFields.get(EsSubjectFields.SUBJECT_NAME);
        if (ObjectUtils.isNotEmpty(nameHighlightField)){
            Text[] fragments = nameHighlightField.fragments();
            StringBuilder stringBuilder = new StringBuilder();
            for (Text fragment : fragments){
                stringBuilder.append(fragment.string());
            }
            result.setSubjectName(stringBuilder.toString());
        }

首先调用hit.getHighlightFields()方法返回一个包含文档中高亮字段的映射,然后从高亮字段映射中获取名为 “SUBJECT_NAME” 的高亮字段(也就是题目名字),从高亮字段中提取相关的文本片段,fragments() 方法返回一个 Text 对象数组,每个 Text 对象表示高亮字段中的一个文本片段。

这里解释一下:

现在假设用户搜索了关键词 “Elasticsearch”,而搜索结果中包含了一篇文章的标题和摘要,其中标题和摘要分别是两个字段。搜索结果如下:

标题:Introduction to Elasticsearch

如果我们对标题和摘要字段都进行了高亮处理,那么可能会得到以下的高亮结果:

高亮标题:Introduction to <span style="background-color: yellow;"> Elastic </span>search

这个时候fragment(段落)的内容是Introduction to <span style="background-color: yellow;"> Elastic </span>search

最后将每个高亮的文本拼接成一个完整的字符串并存储在结果对象的相应属性中,交给前端进行相应的处理,前端可以使用 HTML 和 CSS 来展示高亮文本,通常会将匹配的关键词用特殊样式标记(例如使用 标签添加背景颜色),以使用户能够直观地看到匹配的部分,最后实现高亮效果。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch是一个开源的、分布式的搜索和分析引擎,可以用于存储、搜索和分析各种类型的数据。其中的关键词搜索功能非常强大,并且支持对搜索结果中的关键词进行高亮显示。 在Elasticsearch中,关键词搜索是通过使用查询DSL语句来实现的。用户可以利用Elasticsearch提供的各种查询语句来构建复杂的搜索条件,从而得到符合要求的搜索结果。在查询结果中,如果某个字段中包含了用户输入的关键词Elasticsearch会将这些关键词进行高亮显示,以突出显示搜索结果中的关键信息。 为了实现关键词高亮显示,用户需要在查询DSL语句中设置highlight字段,并指定需要高亮字段名。同时,还可以根据需要设置高亮的标签、前缀和后缀等参数。当搜索结果返回时,Elasticsearch会将匹配到的关键词用指定的标签包裹起来,并添加前缀和后缀,以达到高亮显示效果。 通过关键词搜索高亮功能,用户可以更快速、准确地定位到所需信息。这在很多应用场景下非常有用,比如电商网站的商品搜索、新闻网站的文章搜索等。用户只需输入相关的关键词Elasticsearch会迅速返回匹配的搜索结果,并将关键词搜索结果中进行高亮显示,提供更好的搜索体验。 总之,Elasticsearch中的关键词搜索高亮功能使得用户能够轻松地进行全文搜索,并提供了良好的可定制性,可以根据实际需求设置高亮显示的样式和方式,提升搜索结果的可读性和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值