Spring Boot整合elasticSearch 實(shí)現(xiàn)數(shù)據(jù)高效搜索,實(shí)戰(zhàn)講解!
一、背景介紹
在2018年10月5日,一個(gè)做數(shù)據(jù)搜索服務(wù)的軟件初創(chuàng)公司 Elastic,在納斯達(dá)克上市。
而我們所熟悉的 ElasticSearch,正是 Elastic 公司最出名的產(chǎn)品之一,其中還包括有分布式日志解決方案 ELK(Elastic Search、Logstash、Kibana)、Beats、ECE等。
那 ElasticSearch 究竟是干啥的呢?
本質(zhì)其實(shí)是一個(gè)基于 Lucene 開發(fā)的搜索服務(wù)器,它提供了一個(gè)基于 RESTful web 接口的分布式多用戶能力的全文搜索引擎,能夠達(dá)到實(shí)時(shí)搜索、穩(wěn)定、可靠、快速、安裝使用方便等特點(diǎn)。
同時(shí),作為 Apache 許可條款下的開放源碼,目前已經(jīng)成為一種流行的企業(yè)級(jí)搜索引擎。
既然在企業(yè)開發(fā)中如此流行,肯定少不了 Springboot 的參與,今天我們就一起來探討一下 SpringBoot 與 ElasticSearch 的整合,看看它是否真的如所介紹的那樣優(yōu)秀!
本文主要介紹分為以下幾個(gè)部分:
- 第一部分:環(huán)境準(zhǔn)備,安裝ElasticSearch,安裝 ElasticSearch-head 插件可視化web界面
- 第二部分:SpringBoot 整合 ElasticSearch 開發(fā)
- 第三部分:CRUD 測(cè)試
二、ElasticSearch 安裝
為了和真實(shí)環(huán)境一致,我們采用CentOS7來部署 ElasticSearch 服務(wù)。
建議把所需的安裝包,手動(dòng)從網(wǎng)上下載下來,因?yàn)榉?wù)器下載 ElasticSearch 安裝包速度像蝸牛……,非常非常慢~~,可能是國(guó)內(nèi)的網(wǎng)絡(luò)原因吧!
登錄https://www.elastic.co/cn/downloads/elasticsearch,選擇相應(yīng)的系統(tǒng)環(huán)境下載軟件包,小編我采用的是CentOS,所以選擇Linux環(huán)境。
圖片
2.1、安裝JDK(已經(jīng)安裝過,可以跳過)
Elasticsearch 是用 Java 語言開發(fā)的,所以在安裝之前,需要先安裝一下JDK
yum -y install java-1.8.0-openjdk
查看java安裝情況
java -version
圖片
2.2、安裝ElasticSearch
進(jìn)入到對(duì)應(yīng)上傳的文件夾,安裝ElasticSearch
rpm -ivh elasticsearch-6.1.0.rpm
查找安裝路徑
rpm -ql elasticsearch
一般是裝在/usr/share/elasticsearch/下。
2.3、設(shè)置data的目錄
創(chuàng)建/data/es-data目錄,用于elasticsearch數(shù)據(jù)的存放
mkdir -p /data/es-data
修改該目錄的擁有者為elasticsearch
chown -R elasticsearch:elasticsearch /data/es-data
2.4、設(shè)置log的目錄
mkdir -p /log/es-log
修改該目錄的擁有者為elasticsearch
chown -R elasticsearch:elasticsearch /log/es-log
2.5、修改配置文件elasticsearch.yml
vim /etc/elasticsearch/elasticsearch.yml
修改如下內(nèi)容:
#設(shè)置節(jié)點(diǎn)名稱
cluster.name: my-es
#設(shè)置data存放的路徑為/data/es-data
path.data: /data/es-data
#設(shè)置logs日志的路徑為/log/es-log
path.logs: /log/es-log
#設(shè)置內(nèi)存不使用交換分區(qū),配置了bootstrap.memory_lock為true時(shí)反而會(huì)引發(fā)9200不會(huì)被監(jiān)聽,原因不明
bootstrap.memory_lock: false
#設(shè)置允許所有ip可以連接該elasticsearch
network.host: 0.0.0.0
#開啟監(jiān)聽的端口為9200
http.port: 9200
#增加新的參數(shù),為了讓elasticsearch-head插件可以訪問es (5.x版本,如果沒有可以自己手動(dòng)加)
http.cors.enabled: true
http.cors.allow-origin: "*"
2.6、啟動(dòng)elasticsearch
啟動(dòng)
systemctl start elasticsearch
查看狀態(tài)
systemctl status elasticsearch
設(shè)置開機(jī)啟動(dòng)
systemctl enable elasticsearch
啟動(dòng)成功之后,測(cè)試服務(wù)是否開啟
curl -X GET http://localhost:9200
返回如下信息,說明安裝、啟動(dòng)成功了
圖片
同時(shí)也可以遠(yuǎn)程測(cè)試一下,如果網(wǎng)絡(luò)被拒絕,檢查防火墻是否開啟
#查詢防火墻狀態(tài)
firewall-cmd --state
如果狀態(tài)是active表示已經(jīng)開啟,可以將其關(guān)閉
#關(guān)閉防火墻
systemctl stop firewalld.service
如果不想開機(jī)啟動(dòng),可以輸入如下命令
#禁止firewall開機(jī)啟動(dòng)
systemctl disable firewalld.service
我們?cè)賮頊y(cè)試一下遠(yuǎn)程是否可以正常訪問,結(jié)果如下:
圖片
已經(jīng)可以正常訪問了。
三、ElasticSearch-head 安裝
上面我們介紹了 ElasticSearch 的安裝,但是只能通過接口去查詢數(shù)據(jù),能不能通過可視化界面來查詢數(shù)據(jù)呢?
ElasticSearch-head,就是一個(gè)提供可視化界面的 ElasticSearch 插件,使用 Html5 開發(fā),本質(zhì)上還是一個(gè) 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
移動(dòng)解壓之后的文件夾到/usr/local
mv node-v10.9.0-linux-x64 /usr/local/nodejs
創(chuàng)建軟鏈接,讓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
進(jìn)入elasticsearch-head文件夾
cd elasticsearch-head
因?yàn)閚pm安裝非常非常慢,所以在這里先安裝淘寶源地址,命令如下:
npm install cnpm -g --registry=https://registry.npm.taobao.org
創(chuàng)建cnpm軟鏈接,不然執(zhí)行下面執(zhí)行命令會(huì)報(bào)錯(cuò)
ln -s /usr/local/nodejs/bin/cnpm /usr/local/bin/cnpm
使用cnpm命令下載安裝項(xiàng)目所需要的插件
cnpm install
大概2分鐘之后就安裝好了,安裝完成之后,修改配置信息
vim _site/app.js
圖片
將localhost換成elasticsearch的服務(wù)器地址,小編部署的這臺(tái)是197.168.24.207。
圖片
換完之后,在elasticsearch-head目錄下,輸入如下命令,啟動(dòng)服務(wù)
nohup npm run start &
最后,直接遠(yuǎn)程通過瀏覽器訪問elasticsearch-head可視化管理界面,默認(rèn)訪問地址是ip:9100,訪問結(jié)果如下!
圖片
至此,elasticsearch的安裝包括可視化界面插件elasticsearch-head已經(jīng)完成了!
四、SpringBoot 整合 ElasticSearch
對(duì)于 SpringBoot 來說,ElasticSearch 其實(shí)只是一個(gè)中間件,用途在于提供高效的搜索服務(wù),比較幸運(yùn)的是 SpringBoot 也為我們提供了 ElasticSearch 依賴庫(kù),添加依賴包,通過 JPA 訪問非常方便,整合過程如下!
4.1、創(chuàng)建一個(gè)SpringBoot項(xiàng)目
在pom.xml中,添加依賴庫(kù) 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中添加配置,其中節(jié)點(diǎn)名稱cluster-name需要與上面的配置保持一致!
spring.data.elasticsearch.cluster-name=my-es
spring.data.elasticsearch.cluster-nodes=197.168.24.207:9300
4.1、編寫 CURD
我們先寫一個(gè)的實(shí)體類Student,借助這個(gè)實(shí)體類來完成基礎(chǔ)的 CRUD 功能。
- 新增實(shí)體類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 作為數(shù)據(jù)持久層,接口繼承自ElasticsearchRepository,同時(shí)新增兩個(gè)自定義查詢方法
public interface StudentRepository extends ElasticsearchRepository<Student, String> {
/**
* 通過姓名模擬查詢學(xué)生信息
* @param keyword
* @return
*/
List<Student> findByNameLike(String keyword);
/**
* 自定義查詢,固定匹配查詢學(xué)生信息
* @param keyword
* @return
*/
@Query("{\"match_phrase\":{\"name\":\"?0\"}}")
List<Student> findByNameCustom(String keyword);
}
- 創(chuàng)建控制層,編寫基礎(chǔ)的 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;
}
/**
* 高級(jí)搜索,可以自定義添加搜索字段
* @param keyword
* @return
*/
@GetMapping("/top/search/name")
public Object topSearchTitle(String keyword){
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryStringQuery(keyword))
.build();
//使用searchQuery進(jìn)行搜索
List<Student> students = elasticsearchTemplate.queryForList(searchQuery, Student.class);
return students;
}
}
4.2、CRUD 測(cè)試
CRUD 編寫完了,我們驗(yàn)證一下是否可以正常操作,啟動(dòng) springboot 項(xiàng)目,使用 postman 進(jìn)行測(cè)試。
- 批量新增、新增功能測(cè)試
圖片
圖片
執(zhí)行之后,登錄可視化界面查詢界面,選擇索引student,可以很清晰的看到數(shù)據(jù)已經(jīng)進(jìn)去了
圖片
- 修改功能測(cè)試,修改時(shí)需要傳入ID
圖片
將王小賤從26歲修改為30歲,登錄可視化界面查詢數(shù)據(jù)也已經(jīng)修改成功!
圖片
- 刪除功能測(cè)試,只需要傳入ID
圖片
刪除李四,登錄可視化界面查詢數(shù)據(jù)也已經(jīng)刪除成功!
圖片
- 查詢功能測(cè)試,查詢所有數(shù)據(jù)
圖片
- 查詢功能測(cè)試,查詢指定ID信息
- 查詢功能測(cè)試,普通模糊查詢,ElasticSearch 會(huì)對(duì)關(guān)鍵詞進(jìn)行拆分,只要有包含關(guān)鍵字的都會(huì)查詢出來,例如輸入王張,會(huì)將包含王或者張的姓名信息查詢出來
圖片
- 查詢功能測(cè)試,高級(jí)查詢,這個(gè)是使用官方api提供的查詢?nèi)肟冢梢栽诜椒ㄖ羞M(jìn)行自定義搜索
圖片