springboot——集成elasticsearch进行搜索并高亮关键词

文章介绍了Elasticsearch作为分布式搜索和分析引擎的核心特性,包括基于Lucene的倒排索引机制,以及如何在SpringBoot应用中进行集成和实现搜索高亮。同时,提到了Elasticsearch在NoSQL环境中的应用,以及与传统SQL的全表检索效率对比。

目录

1.elasticsearch概述

3.springboot集成elasticsearch

4.实现搜索并高亮关键词


1.elasticsearch概述

(1)是什么:

Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。

Lucene 可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。但Lucene 只是一个基于java下的库,需要使用 Java 并要将其集成到你的应用中才可进行使用。而Elasticsearch 则是基于Lucene 下实现的开源搜索引擎。

Elasticsearch 基于分布式进行实时文件存储,每个字段都被索引并可被搜索,并可进行实时分析。同事由于基于分布式,可以扩展到上百台服务器,处理PB级结构化或非结构化数据。

(2)核心概念:

elasticsearch可归类于NoSQL的一种,其主要包含index(索引)、type(类型,elasticsearch 7.x后已被舍弃)、Document(文档)、Fields(字段)。

类比于MySQL如下:

其实现的核心在于倒排索引: 指的是将文档内容中的单词作为索引,将包含该词的文档 ID 作为记录。

一般的sql中都是正排索引,即以表中的唯一标识id作为索引,通过主键索引找到文档其他内容(具体请参考mysql存储结构)。

而elasticsearch通过关键字作为索引反向找到文档ID,可以高效的实现全文检索。

如我们有以下两条记录:

idcontentwriter
1这是一条测试数据,测试elasticsearchseven
2这是第二条、测试数据,试一下elasticsearch搜索seven

以上两条数据,在mysql中id为主键,当我们以elasticsearch以关键词搜索去搜查所有和elasticsearch有关的content时,在没有为content建索引的情况下,无法走主键索引,mysql会进行全表检索,效率一般。

而elasticsearch中会为content建立倒排索引,根据content找到对应的id,返回搜索结果,效率快鱼mysql。并且,整个搜索过程中我们不需要做任何文本的模糊匹配。

(3)应用场景:

ElasticSearch作为一个便于使用的分布式全文搜索引擎,常被用于各种搜索场景中:

  • 维基百科,百度等搜索引擎,对关键词和内容概要进行匹对,并对搜索的关键词进行高亮。
  • 电商平台,对关键词和商品名称、标题进行匹配,并对对搜索的关键词进行高亮。
  • 论坛,对关键词和帖子内容及评论等快速匹配,并对搜索关键词进行高亮。

总之言之, ElasticSearch是一个优秀的检索工具,可以对各类内容进行快速检索,并返回结果:

(检索关键词并进行高亮)

一般情况我们会在数据存入数据库前,把需要检索的字段作为ElasticSearch的索引和需要返回的数据存入ElasticSearch(比如电商平台达到商品标题),然后在搜索时使用ElasticSearch进行全文检索,快速返回相关结果。

3.springboot集成elasticsearch

下面对springboot集成elasticsearch进行演示:

pom依赖文件:

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>

    <dependencies>
        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>
        <!-- ElasticSearch -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- lombok 需要安装插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

此处需要注意的是springboot自带的ElasticSearch版本为6.8.5 ,如果你使用的是其他版本的ElasticSearch请注意指定版本号。

config配置文件,对ElasticSearch进行连接:

@Configuration
public class ElasticSearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1",9200,"http")
                )
        );
        return client;
    }
}

至此,我们皆可以通过 RestHighLevelClient 对ElasticSearch进行使用

4.实现搜索并高亮关键词

下面对 ElasticSearch进行使用,进行查询并高亮关键词。

首先我们建立索引:user,并存入以下数据:

然后,我们在业务类编写查询方法:

//查询
    public List<User> searchUserByKeyword(String keyword,int pageNo,int pageSize) throws IOException {
        if (pageNo<=1){
            pageNo=1;
        }
        //条件查询
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //分页
        searchSourceBuilder.from(pageNo);
        searchSourceBuilder.size(pageSize);

        //匹配关键词(类似于模糊查询)
        //MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("sign",keyword);
        //组合查询
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //and查询,所有条件都要符合;    or查询可以使用queryBuilder.should
        queryBuilder.must(QueryBuilders.matchQuery("sign",keyword));
        queryBuilder.must(QueryBuilders.matchQuery("statue","use"));
        //精确匹配
        //TermQueryBuilder queryBuilder = QueryBuilders.termQuery("sign",keyword);
        searchSourceBuilder.query(queryBuilder);

        //设置高亮
        //highlightBuilder.requireFieldMatch(false);   //只需要高亮第一个
        searchSourceBuilder.highlighter(new HighlightBuilder().field("sign"));

        //执行
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //解析结果
        List<User> list = new ArrayList<>();
        for (SearchHit hit: response.getHits().getHits()){
            //解析高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField sign = highlightFields.get("sign");
            //获取原字段
            Map<String, Object> oldUser = hit.getSourceAsMap();
            //将高亮替换原字段内容
            StringBuilder stringBuilder = new StringBuilder();
            if (sign!=null){
                Text[] texts = sign.fragments();
                for (Text t:texts){
                    stringBuilder.append(t);
                }
                log.info("替换:"+stringBuilder);
                oldUser.put("sign",stringBuilder.toString());
            }

            User user = JSONObject.parseObject(hit.getSourceAsString(),User.class);
            user.setSign(oldUser.get("sign").toString());
            list.add(user);
        }
       return list;
    }

ElasticSearch的match配置是拆字匹配,即关键词为“测试”,那么会查询出所有目标字段中包含“测”和“试”任一字符的结果;若为“java”则不会对字母进行拆分,会保持整个单词完整。

上述代码需要注意的是,高亮的字段必须是查询的字段,才可以对查询的关键词进行高亮处理,否则高亮字段会为空。

编写controller进行测试:

@RestController
public class SearchController {

    @Resource
    private SearchService searchService;

    @GetMapping("/test")
    public List<User> test(@RequestParam("keyword")String keyword) throws IOException {
        return searchService.searchUserByKeyword(keyword,0,5);
    }
}

结果:

成功查询所有sign包含java关键词且statue为use的用户,并对java关键词进行高亮(em标签,需要使用html进行解析)。

拓展:

(1)ElasticSearch还可以对搜索结果进行排序:

searchSourceBuilder.sort("age");

上述代码即根据age字段对搜索结果进行排序。

(2)过滤查询条件:

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //过滤statue!=use的数据
        queryBuilder.filter(QueryBuilders.matchPhraseQuery("statue","use"));
        //过滤age不大于20的数据
        queryBuilder.filter(QueryBuilders.rangeQuery("age").gt(20));

具体还有很多查询条件,具体可参考ElasticSearch官网文档。

Elasticsearch 简介 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。elasticSearch 的使用场景 1、在海量数据前提下,对数据进行检索。比如:京东,淘宝等电商项目课程目标: 1. 了解企业级搜索引擎2. 安装elasticsearch 课程目录: 01 课程介绍02 elasticsearch 简介03 elasticsearch 使用场景04 安装elasticsearch 之前先安装jdk05 安装elasticsearch06 测试elasticsearch是否安装成功 07 安装kibana08 elasticsearch 基本认识 以及添加索引和删除索引09 elasticsearch 添加查询数据10 elasticsearch 修改删除数据11 elasticsearch 有条件的查询12 分词子属性fuzzy查询13 elasticsearch 过滤使用14 elasticsearch 排序与分页15 elasticsearch 如何查询指定的字段16 elasticsearch 高亮显示17 elasticsearch 聚合18 elasticsearch mapping 概念19 elasticsearch 的中文词库20 elasticsearch 中文词库安装测试21 elasticsearch 中文词库的使用案例22 elasticsearch 自定义词库配置23 安装nginx 配置中文词库24 测试elasticsearch 自定义中文词库25 搭建项目父工程26 搭建项目bean-interface-common27 搭建search 的service web 项目28 测试项目是否能与elasticsearch联通29 创建数据库搭建首页30 数据上传功能的实现类完成31 数据上传控制器完成32 dubbo 介绍以及安装zookeeper33 将数据从mysql 上传到elasticsearch 中34 elasticsearch查询功能分析35 编写业务需求的dsl 语句36 编写输入参数返回结果集的实体类37 实现类编写38 编写实现类中dsl 语句39 返回集结果转换40 结果测试41 测试通过输入查询条件将数据显示到页面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值