Spring Boot整合elasticSearch 实现数据高效搜索,实战讲解!

开发 前端
那 ElasticSearch 究竟是干啥的呢?本质其实是一个基于 Lucene 开发的搜索服务器,它提供了一个基于 RESTful web 接口的分布式多用户能力的全文搜索引擎,能够达到实时搜索、稳定、可靠、快速、安装使用方便等特点。同时,作为 Apache 许可条款下的开放源码,目前已经成为一种流行的企业级搜索引擎。

一、背景介绍

在2018年10月5日,一个做数据搜索服务的软件初创公司 Elastic,在纳斯达克上市。

而我们所熟悉的 ElasticSearch,正是 Elastic 公司最出名的产品之一,其中还包括有分布式日志解决方案 ELK(Elastic Search、Logstash、Kibana)、Beats、ECE等。

那 ElasticSearch 究竟是干啥的呢?

本质其实是一个基于 Lucene 开发的搜索服务器,它提供了一个基于 RESTful web 接口的分布式多用户能力的全文搜索引擎,能够达到实时搜索、稳定、可靠、快速、安装使用方便等特点。

同时,作为 Apache 许可条款下的开放源码,目前已经成为一种流行的企业级搜索引擎。

既然在企业开发中如此流行,肯定少不了 Springboot 的参与,今天我们就一起来探讨一下 SpringBoot 与 ElasticSearch 的整合,看看它是否真的如所介绍的那样优秀!

本文主要介绍分为以下几个部分:

  • 第一部分:环境准备,安装ElasticSearch,安装 ElasticSearch-head 插件可视化web界面
  • 第二部分:SpringBoot 整合 ElasticSearch 开发
  • 第三部分:CRUD 测试

二、ElasticSearch 安装

为了和真实环境一致,我们采用CentOS7来部署 ElasticSearch 服务。

建议把所需的安装包,手动从网上下载下来,因为服务器下载 ElasticSearch 安装包速度像蜗牛……,非常非常慢~~,可能是国内的网络原因吧!

登录https://www.elastic.co/cn/downloads/elasticsearch,选择相应的系统环境下载软件包,小编我采用的是CentOS,所以选择Linux环境。

图片图片

2.1、安装JDK(已经安装过,可以跳过)

Elasticsearch 是用 Java 语言开发的,所以在安装之前,需要先安装一下JDK

yum -y install java-1.8.0-openjdk
  • 1.

查看java安装情况

java -version
  • 1.

图片图片

2.2、安装ElasticSearch

进入到对应上传的文件夹,安装ElasticSearch

rpm -ivh elasticsearch-6.1.0.rpm
  • 1.

查找安装路径

rpm -ql elasticsearch
  • 1.

一般是装在/usr/share/elasticsearch/下。

2.3、设置data的目录

创建/data/es-data目录,用于elasticsearch数据的存放

mkdir -p /data/es-data
  • 1.

修改该目录的拥有者为elasticsearch

chown -R elasticsearch:elasticsearch /data/es-data
  • 1.

2.4、设置log的目录

mkdir -p /log/es-log
  • 1.

修改该目录的拥有者为elasticsearch

chown -R elasticsearch:elasticsearch /log/es-log
  • 1.

2.5、修改配置文件elasticsearch.yml

vim /etc/elasticsearch/elasticsearch.yml
  • 1.

修改如下内容:

#设置节点名称
cluster.name: my-es

#设置data存放的路径为/data/es-data
path.data: /data/es-data

#设置logs日志的路径为/log/es-log
path.logs: /log/es-log

#设置内存不使用交换分区,配置了bootstrap.memory_lock为true时反而会引发9200不会被监听,原因不明
bootstrap.memory_lock: false

#设置允许所有ip可以连接该elasticsearch
network.host: 0.0.0.0

#开启监听的端口为9200
http.port: 9200

#增加新的参数,为了让elasticsearch-head插件可以访问es (5.x版本,如果没有可以自己手动加)
http.cors.enabled: true
http.cors.allow-origin: "*"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

2.6、启动elasticsearch

启动

systemctl start elasticsearch
  • 1.

查看状态

systemctl status elasticsearch
  • 1.

设置开机启动

systemctl enable elasticsearch
  • 1.

启动成功之后,测试服务是否开启

curl -X GET http://localhost:9200
  • 1.

返回如下信息,说明安装、启动成功了

图片图片

同时也可以远程测试一下,如果网络被拒绝,检查防火墙是否开启

#查询防火墙状态
firewall-cmd --state
  • 1.
  • 2.

如果状态是active表示已经开启,可以将其关闭

#关闭防火墙
systemctl stop firewalld.service
  • 1.
  • 2.

如果不想开机启动,可以输入如下命令

#禁止firewall开机启动
systemctl disable firewalld.service
  • 1.
  • 2.

我们再来测试一下远程是否可以正常访问,结果如下:

图片图片

已经可以正常访问了。

三、ElasticSearch-head 安装

上面我们介绍了 ElasticSearch 的安装,但是只能通过接口去查询数据,能不能通过可视化界面来查询数据呢?

ElasticSearch-head,就是一个提供可视化界面的 ElasticSearch 插件,使用 Html5 开发,本质上还是一个 nodejs 的工程,因此在使用之前需要先安装 nodeJs。

3.1、安装 nodeJs

下载nodeJS

wget https://nodejs.org/dist/v10.9.0/node-v10.9.0-linux-x64.tar.gz
  • 1.

解压下载包

tar -zxvf node-v10.9.0-linux-x64.tar.gz
  • 1.

移动解压之后的文件夹到/usr/local

mv node-v10.9.0-linux-x64 /usr/local/nodejs
  • 1.

创建软链接,让npm和node命令全局生效

ln -s /usr/local/nodejs/bin/node /usr/bin/node
ln -s /usr/local/nodejs/bin/npm /usr/bin/npm
  • 1.
  • 2.

查看nodejs是否安装成功

node -v
npm -v
  • 1.
  • 2.

图片图片

3.2、 安装 elasticsearch-head

如果未安装git ,则先安装git工具

yum install –y git
  • 1.

查看git安装情况

git --version
  • 1.

图片图片

从 gitHub 上拉取 elasticsearch-head 插件代码

git clone https://github.com/mobz/elasticsearch-head.git
  • 1.

进入elasticsearch-head文件夹

cd elasticsearch-head
  • 1.

因为npm安装非常非常慢,所以在这里先安装淘宝源地址,命令如下:

npm install cnpm -g --registry=https://registry.npm.taobao.org
  • 1.

创建cnpm软链接,不然执行下面执行命令会报错

ln -s /usr/local/nodejs/bin/cnpm /usr/local/bin/cnpm
  • 1.

使用cnpm命令下载安装项目所需要的插件

cnpm install
  • 1.

大概2分钟之后就安装好了,安装完成之后,修改配置信息

vim _site/app.js
  • 1.

图片图片

将localhost换成elasticsearch的服务器地址,小编部署的这台是197.168.24.207。

图片图片

换完之后,在elasticsearch-head目录下,输入如下命令,启动服务

nohup npm run start &
  • 1.

最后,直接远程通过浏览器访问elasticsearch-head可视化管理界面,默认访问地址是ip:9100,访问结果如下!

图片图片

至此,elasticsearch的安装包括可视化界面插件elasticsearch-head已经完成了!

四、SpringBoot 整合 ElasticSearch

对于 SpringBoot 来说,ElasticSearch 其实只是一个中间件,用途在于提供高效的搜索服务,比较幸运的是 SpringBoot 也为我们提供了 ElasticSearch 依赖库,添加依赖包,通过 JPA 访问非常方便,整合过程如下!

4.1、创建一个SpringBoot项目

在pom.xml中,添加依赖库 ElasticSearch 依赖包

<!--jpa 支持-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--elasticsearch-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

在application.properties中添加配置,其中节点名称cluster-name需要与上面的配置保持一致!

spring.data.elasticsearch.cluster-name=my-es
spring.data.elasticsearch.cluster-nodes=197.168.24.207:9300
  • 1.
  • 2.

4.1、编写 CURD

我们先写一个的实体类Student,借助这个实体类来完成基础的 CRUD 功能。

  • 新增实体类Student,其中indexName表示索引,type表示索引类别
@Data
@Accessors(chain = true)
@Document(indexName = "student", type = "school")
public class Student {

    private static final long serialVersionUID = 1l;

    @Id
    private String id;

    private String name;

    private String gender;

    private Integer age;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

注意id字段是必须的,可以不写注解@Id!

  • 使用 JPA 作为数据持久层,接口继承自ElasticsearchRepository,同时新增两个自定义查询方法
public interface StudentRepository extends ElasticsearchRepository<Student, String> {

    /**
     * 通过姓名模拟查询学生信息
     * @param keyword
     * @return
     */
    List<Student> findByNameLike(String keyword);

    /**
     * 自定义查询,固定匹配查询学生信息
     * @param keyword
     * @return
     */
    @Query("{\"match_phrase\":{\"name\":\"?0\"}}")
    List<Student> findByNameCustom(String keyword);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 创建控制层,编写基础的 CRUD 功能
@RestController
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private StudentRepository studentRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 批量添加
     * @param students
     * @return
     */
    @PostMapping("/batchAdd")
    public void add(@RequestBody List<Student> students){
        studentRepository.saveAll(students);
    }

    /**
     * 添加
     * @param student
     * @return
     */
    @PostMapping("/add")
    public void add(@RequestBody Student student){
        studentRepository.save(student);
    }

    /**
     * 修改
     * @param student
     * @return
     */
    @PostMapping("/update")
    public void updateById(@RequestBody Student student){
        studentRepository.save(student);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @PostMapping("/delete/{id}")
    public void deleteById(@PathVariable String id){
        studentRepository.deleteById(id);
    }

    /**
     * 获取所有信息
     * @return
     */
    @GetMapping("/get")
    public Object getAll(){
        Iterable<Student> iterable = studentRepository.findAll();
        List<Student> list = new ArrayList<>();
        iterable.forEach(list :: add);
        return list;
    }

    /**
     * 查询指定ID
     * @param id
     * @return
     */
    @GetMapping("/get/{id}")
    public Object getById(@PathVariable String id){
        if(StringUtils.isEmpty(id)){
            return Result.error();
        }
        Optional<Student> studentOptional = studentRepository.findById(id);
        if(studentOptional.isPresent()){
            return studentOptional.get();
        }
        return null;
    }


    /**
     * 普通搜索
     * @param keyword
     * @return
     */
    @GetMapping("/search/name")
    public Object searchName(String keyword){
        List<Student> students = studentRepository.findByNameLike(keyword);
        return students;
    }

    /**
     * 自定义匹配
     * 普通搜索
     * @param keyword
     * @return
     */
    @GetMapping("/search/name/custom")
    public Object searchTitleCustom(String keyword){
        List<Student> students = studentRepository.findByNameCustom(keyword);
        return students;
    }

    /**
     * 高级搜索,可以自定义添加搜索字段
     * @param keyword
     * @return
     */
    @GetMapping("/top/search/name")
    public Object topSearchTitle(String keyword){
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryStringQuery(keyword))
                .build();
        //使用searchQuery进行搜索
        List<Student> students = elasticsearchTemplate.queryForList(searchQuery, Student.class);
        return students;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.

4.2、CRUD 测试

CRUD 编写完了,我们验证一下是否可以正常操作,启动 springboot 项目,使用 postman 进行测试。

  • 批量新增、新增功能测试

图片图片

图片图片

执行之后,登录可视化界面查询界面,选择索引student,可以很清晰的看到数据已经进去了

图片图片

  • 修改功能测试,修改时需要传入ID

图片图片

将王小贱从26岁修改为30岁,登录可视化界面查询数据也已经修改成功!

图片图片

  • 删除功能测试,只需要传入ID

图片图片

删除李四,登录可视化界面查询数据也已经删除成功!

图片图片

  • 查询功能测试,查询所有数据

图片图片

  • 查询功能测试,查询指定ID信息
  • 查询功能测试,普通模糊查询,ElasticSearch 会对关键词进行拆分,只要有包含关键字的都会查询出来,例如输入王张,会将包含王或者张的姓名信息查询出来

图片图片

  • 查询功能测试,高级查询,这个是使用官方api提供的查询入口,可以在方法中进行自定义搜索

图片图片

责任编辑:武晓燕 来源: 潘志的研发笔记
相关推荐

2023-09-01 08:46:44

2022-05-30 07:31:38

SpringBoot搜索技巧

2017-05-19 14:47:24

Spring Boot Elasticsea场景

2024-06-05 08:14:26

SpringElasticsea人脸数据

2021-12-27 09:59:57

SpringCanal 中间件

2024-03-26 08:08:08

SpringBPMN模型

2017-04-17 10:35:40

Spring BooRedis 操作

2024-08-13 10:36:25

SpringScrew数据库

2024-11-04 08:02:23

SpringRabbitMQ中间件

2025-03-26 03:25:00

SpringGuavaCaffeine

2024-01-30 08:01:15

RabbitMQ业务逻辑应用场景

2025-02-21 16:00:00

SpringBoot代码开发

2022-01-04 19:15:33

ElasticsearSpring BootLogstash

2024-10-30 08:05:01

Spring参数电子签章

2022-12-23 08:28:42

策略模式算法

2016-03-04 10:50:02

ios圆角高效添加

2022-05-18 12:04:19

Mybatis数据源Spring

2017-10-17 15:14:33

Spring BooThymeleafWeb

2022-07-21 11:04:53

Swagger3Spring

2024-12-24 08:44:55

ActiveMQRabbitMQ交换机
点赞
收藏

51CTO技术栈公众号