Python实战社群
Java实战社群
长按识别下方二维码,按需求添加
扫码关注添加客服
进Python社群▲
扫码关注添加客服
进Java社群▲
作者丨鸭血粉丝
来源丨Java极客技术
一、介绍
在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
查看java安装情况
java -version
2.2、安装ElasticSearch
进入到对应上传的文件夹,安装ElasticSearch
rpm -ivh elasticsearch-6.1.0.rpm
查找安装路径
rpm -ql elasticsearch
一般是装在/usr/share/elasticsearch/
下。
2.3、设置data的目录
创建/data/es-data
目录,用于elasticsearch数据的存放
mkdir -p /data/es-data
修改该目录的拥有者为elasticsearch
chown -R elasticsearch:elasticsearch /data/es-data
2.4、设置log的目录
mkdir -p /log/es-log
修改该目录的拥有者为elasticsearch
chown -R elasticsearch:elasticsearch /log/es-log
2.5、修改配置文件elasticsearch.yml
vim /etc/elasticsearch/elasticsearch.yml
修改如下内容:
#设置节点名称
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: "*"
2.6、启动elasticsearch
启动
systemctl start elasticsearch
查看状态
systemctl status elasticsearch
设置开机启动
systemctl enable elasticsearch
启动成功之后,测试服务是否开启
curl -X GET http://localhost:9200
返回如下信息,说明安装、启动成功了
同时也可以远程测试一下,如果网络被拒绝,检查防火墙是否开启
#查询防火墙状态
firewall-cmd --state
如果状态是active
表示已经开启,可以将其关闭
#关闭防火墙
systemctl stop firewalld.service
如果不想开机启动,可以输入如下命令
#禁止firewall开机启动
systemctl disable firewalld.service
我们再来测试一下远程是否可以正常访问,结果如下:
已经可以正常访问了。
三、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
解压下载包
tar -zxvf node-v10.9.0-linux-x64.tar.gz
移动解压之后的文件夹到/usr/local
mv node-v10.9.0-linux-x64 /usr/local/nodejs
创建软链接,让npm
和node
命令全局生效
ln -s /usr/local/nodejs/bin/node /usr/bin/node
ln -s /usr/local/nodejs/bin/npm /usr/bin/npm
查看nodejs
是否安装成功
node -v
npm -v
3.2、 安装 elasticsearch-head
如果未安装git
,则先安装git
工具
yum install –y git
查看git
安装情况
git --version
从 gitHub 上拉取 elasticsearch-head 插件代码
git clone https://github.com/mobz/elasticsearch-head.git
进入elasticsearch-head
文件夹
cd elasticsearch-head
因为npm
安装非常非常慢,所以在这里先安装淘宝源地址,命令如下:
npm install cnpm -g --registry=https://registry.npm.taobao.org
创建cnpm
软链接,不然执行下面执行命令会报错
ln -s /usr/local/nodejs/bin/cnpm /usr/local/bin/cnpm
使用cnpm
命令下载安装项目所需要的插件
cnpm install
大概2分钟之后就安装好了,安装完成之后,修改配置信息
vim _site/app.js
将localhost
换成elasticsearch
的服务器地址,小编部署的这台是197.168.24.207
。
换完之后,在elasticsearch-head
目录下,输入如下命令,进入启动目录
cd node_modules/grunt/bin
使用如下命令启动服务,使elasticsearch-head
服务在后台运行!
nohup ./grunt server &
最后,直接远程通过浏览器访问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>
在application.properties
中添加配置,其中节点名称cluster-name
需要与上面的配置保持一致!
spring.data.elasticsearch.cluster-name=my-es
spring.data.elasticsearch.cluster-nodes=197.168.24.207:9300
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;
}
注意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);
}
创建控制层,编写基础的 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;
}
}
4.2、CRUD 测试
CRUD 编写完了,我们验证一下是否可以正常操作,启动 springboot 项目,使用 postman 进行测试。
批量新增、新增功能测试
执行之后,登录可视化界面查询界面,选择索引student
,可以很清晰的看到数据已经进去了
修改功能测试,修改时需要传入
ID
将王小贱从26岁修改为30岁,登录可视化界面查询数据也已经修改成功!
删除功能测试,只需要传入
ID
删除李四,登录可视化界面查询数据也已经删除成功!
查询功能测试,查询所有数据
查询功能测试,查询指定
ID
信息
查询功能测试,普通模糊查询,ElasticSearch 会对关键词进行拆分,只要有包含关键字的都会查询出来,例如输入
王张
,会将包含王
或者张
的姓名信息查询出来
查询功能测试,高级查询,这个是使用官方api提供的查询入口,可以在方法中进行自定义搜索
五、总结
elasticsearch 在海量数据查询方面,非常高效,本来想写在大量数据查询方面,数据库与 elasticsearch 的查询效率比对,由于篇幅较长会造成阅读体验降低,后在下篇文章中再次介绍这个部分。
对于想学习 elasticsearch 的新手,尤其是安装部分可能比较困难,因此花的编写时间比较多,后续的整合都比较简单,elasticsearch 真正的强大的地方在于高效信息搜索,本篇对 elasticsearch 的搜索只是做一个基础的介绍,具体的高级搜索方法大家可以参考官方文档 API,本篇可以看作为 elasticsearch 搜索服务入门的教程,可能也有遗漏的地方,欢迎网友点评、吐槽!
后说两句(求关注)
最近大家应该发现微信公众号信息流改版了吧,再也不是按照时间顺序展示了。这就对阿粉这样的坚持的原创小号主,可以说非常打击,阅读量直线下降,正反馈持续减弱。
所以看完文章,哥哥姐姐们给阿粉来个在看吧,让阿粉拥有更加大的动力,写出更好的文章,拒绝白嫖,来点正反馈呗~。
如果想在第一时间收到阿粉的文章,不被公号的信息流影响,那么可以给Java极客技术设为一个星标。
最后感谢各位的阅读,才疏学浅,难免存在纰漏,如果你发现错误的地方,由于本号没有留言功能,还请你在后台留言指出,我对其加以修改。
最后谢谢大家支持~
程序员专栏 扫码关注填加客服 长按识别下方二维码进群
近期精彩内容推荐: 拍一拍,微信史上最短一行代码 如果张东升是个程序员 4300 字Python列表使用总结,用心! 大白话java多线程,高手勿入
在看点这里好文分享给更多人↓↓