六.全文检索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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
162 1
Elasticsearch 7.8.0从入门到精通
|
3月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
3月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
108 12
|
1月前
|
存储 JSON Java
ELK 圣经:Elasticsearch、Logstash、Kibana 从入门到精通
ELK是一套强大的日志管理和分析工具,广泛应用于日志监控、故障排查、业务分析等场景。本文档将详细介绍ELK的各个组件及其配置方法,帮助读者从零开始掌握ELK的使用。
|
4月前
|
JSON 搜索推荐 数据挖掘
ElasticSearch的简单介绍与使用【入门篇】
这篇文章是Elasticsearch的入门介绍,涵盖了Elasticsearch的基本概念、特点、安装方法以及如何进行基本的数据操作,包括索引文档、查询、更新、删除和使用bulk API进行批量操作。
ElasticSearch的简单介绍与使用【入门篇】
|
3月前
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
|
3月前
|
JSON 监控 Java
Elasticsearch 入门:搭建高性能搜索集群
【9月更文第2天】Elasticsearch 是一个分布式的、RESTful 风格的搜索和分析引擎,基于 Apache Lucene 构建。它能够处理大量的数据,提供快速的搜索响应。本教程将指导你如何从零开始搭建一个基本的 Elasticsearch 集群,并演示如何进行简单的索引和查询操作。
279 3
|
4月前
|
JSON 测试技术 API
黑马商城 Elasticsearch从入门到部署 RestClient操作文档
这篇文章详细介绍了如何使用Java的RestHighLevelClient客户端与Elasticsearch进行文档操作,包括新增、查询、删除、修改文档以及批量导入文档的方法,并提供了相应的代码示例和操作步骤。
|
4月前
|
JSON 自然语言处理 Java
Elasticsearch从入门到部署 文档操作 RestAPI
这篇文章详细介绍了Elasticsearch中文档的增删改查操作,并通过Java的RestHighLevelClient客户端演示了如何通过REST API与Elasticsearch进行交云,包括初始化客户端、索引库的创建、删除和存在性判断等操作。
|
4月前
|
JSON 自然语言处理 数据库
Elasticsearch从入门到项目部署 安装 分词器 索引库操作
这篇文章详细介绍了Elasticsearch的基本概念、倒排索引原理、安装部署、IK分词器的使用,以及如何在Elasticsearch中进行索引库的CRUD操作,旨在帮助读者从入门到项目部署全面掌握Elasticsearch的使用。