六.全文检索ElasticSearch经典入门-高亮

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 六.全文检索ElasticSearch经典入门-高亮

前言

本篇文章我们来学习一下如何使用ElasticSearch实现搜索字段的高亮,许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。在 Elasticsearch 中检索出高亮片段也很容易。

使用Kibana演示高亮

ElasticSearch允许给搜索的字段进行高亮显示,下面是天猫的搜索效果如下:
在这里插入图片描述
我们通过开发工具分析所谓的高亮就是给搜索的关键字加上颜色样式,当然也可以加上其他样式,如下
在这里插入图片描述
下面是使用Kibana演示给ES搜索的结果增加高亮效果语法如下

GET /_search
{
   
   
    "query" : {
   
   
        "match": {
   
    "content": "kimchy" }
    },
    "highlight" : {
   
   
        "fields" : {
   
   
            "field": {
   
   
                "pre_tags": [
                    "<span style='color:red'>"
                ],
                "post_tags": [
                    "</span>"
                ]
            }
        }
    }
}

下面是演示效果
在这里插入图片描述
当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分。这个部分包含了 title属性匹配的文本片段,并以 HTML 标签 封装来达到高亮效果。

高亮代码实战

下面案例基于 《ElasticSearch Java实战》的DSL查询案例进行开发,使用ES我们可以轻松做到高亮功能,第一步:增加结果处理器,在集成SpringBoot之后高亮功能失效,需要做高亮结果处理。

@Component
public class HighlightResultMapper implements SearchResultMapper {
   
   

    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
   
   
        // 记录总条数
        long totalHits = response.getHits().getTotalHits();
        // 记录列表(泛型) - 构建Aggregate使用
        List<T> list = Lists.newArrayList();
        // 获取搜索结果(真正的的记录)
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
   
   
            if(hits.getHits().length <= 0){
   
   
                return null;
            }
            // 将原本的JSON对象转换成Map对象
            Map<String, Object> map = hit.getSourceAsMap();
            // 获取高亮的字段Map
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            for (Map.Entry<String, HighlightField> highlightField : highlightFields.entrySet()) {
   
   
                // 获取高亮的Key
                String key = highlightField.getKey();
                // 获取高亮的Value
                HighlightField value = highlightField.getValue();
                // 实际fragments[0]就是高亮的结果,无需遍历拼接
                Text[] fragments = value.getFragments();
                StringBuilder sb = new StringBuilder();
                for (Text text : fragments) {
   
   
                    sb.append(text);
                }
                // 因为高亮的字段必然存在于Map中,就是key值
                // 可能有一种情况,就是高亮的字段是嵌套Map,也就是说在Map里面还有Map的这种情况,这里没有考虑
                map.put(key, sb.toString());
            }
            // 把Map转换成对象
            T item = JSON.parseObject(JSONObject.toJSONString(map),aClass);
            list.add(item);
        }
        // 返回的是带分页的结果
        return new AggregatedPageImpl<>(list, pageable, totalHits,response.getAggregations());
    }

    public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
   
   
        return null;
    }
}

该结果映射器把高亮结果进行了映射,同时还对聚合结果进行了映射。

第二步:给搜索的字段设置高亮,通过builder.withHighlightFields设置高亮


@Autowired
private CourseRepository repository;

@Autowired
private ElasticsearchRestTemplate template;

@Autowired
private HighlightResultMapper highlightResultMapper;

...省略...

@Test
public void testSearch(){
   
   

    //查询构建器
    NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

    //设置分页: 第2页 (0开始), 每页10数
    builder.withPageable(PageRequest.of(1,10));
    //设置排序 : 金额倒排
    builder.withSort(SortBuilders.fieldSort("amount").order(SortOrder.DESC));

    //构建组合查询
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

    //标题包含鼠标
    boolQuery.must(QueryBuilders.matchQuery("title","鼠标"))
            //状态值查询
            .filter(QueryBuilders.termQuery("status",1))
            //金额范围查询
            .filter(QueryBuilders.rangeQuery("amount").gte(10).lte(2000));

    //添加查询条件
    builder.withQuery(boolQuery);

    //===============================================================================
    //给title字段设置高亮,使用color:red来高亮
    HighlightBuilder.Field  highlightField = new HighlightBuilder.Field("title")
                    .preTags("<span style='color:red'>")
                    .postTags("</span>");

    builder.withHighlightFields(highlightField);
    //================================================================================

   //Page<OrderDoc> page = orderRepository.search(builder.build());
   Page<OrderDoc> page = template.queryForPage(builder.build(), OrderDoc.class, highlightResultMapper);

   //获取条数
   System.out.println("总元素个数:"+page.getTotalElements());
   //打印列表
   page.getContent().forEach(System.out::print);


}

打印结果如下:

总元素个数:3
OrderDoc(id=2, title=买了一个<span style='color:red'>鼠标</span>, count=1, status=1, amount=200)
OrderDoc(id=1, title=买了一个<span style='color:red'>鼠标</span>, count=1, status=1, amount=200)
OrderDoc(id=3, title=买了一个<span style='color:red'>鼠标</span>, count=1, status=1, amount=200)

我们看到 <span style='color:red'>鼠标</span> 说明高亮成功


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
3月前
|
安全 Linux 开发工具
Elasticsearch 搜索入门技术之一
Elasticsearch 搜索入门技术之一
227 1
|
4月前
|
JSON 自然语言处理 数据库
数据库-ElasticSearch入门(索引、文档、查询)
数据库-ElasticSearch入门(索引、文档、查询)
290 0
|
6月前
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
2月前
|
存储 关系型数据库 MySQL
ElasticSearch 入门
【2月更文挑战第7天】ElasticSearch 入门 简介 ElasticSearch 的基本概念 ElasticSearch 的查询流程 ElasticSearch 的更新流程
37 2
|
2月前
|
存储 自然语言处理 搜索推荐
ElasticSearch入门篇
ElasticSearch入门篇
|
4月前
|
存储 Java 网络架构
Spring Data Elasticsearch基础入门详解
Spring Data Elasticsearch基础入门详解
124 0
|
4月前
|
存储 数据挖掘 Java
Elasticsearch基础入门与安装部署
Elasticsearch基础入门与安装部署
170 0
|
4月前
|
存储 JSON Java
SpringBoot - 信息检索与ElasticSearch入门
SpringBoot - 信息检索与ElasticSearch入门
37 0
|
5月前
|
索引
ElasticSearch入门
ElasticSearch入门
|
6月前
|
Web App开发 自然语言处理 API
5000字详说Elasticsearch入门(一)
本文主要介绍快速入门Elasticsearch,从安装、基本概念、分词器、文档基本操作这4个方面快速入门。本篇是ES入门系列的第一篇,后续还有springboot项目集成ES、ES高级查询用法、数据库同步到ES的方案等。
5000字详说Elasticsearch入门(一)

热门文章

最新文章