原創 | 一篇解決Springboot 整合 Elasticsearch
- 2020 年 1 月 14 日
- 筆記
大家好,我是潤森。期末已掛,誰來燒紙。
昨天我發現IDEA
過期了,十分鐘解決了。公眾號回復 IDEA
就ok

ElasticSearch
結合業務的場景,在目前的商品體系需要構建搜索服務,主要是為了提供用戶更豐富的檢索場景以及高速,實時及性能穩定的搜索服務。
ElasticSearch
是一個基於Lucene
的搜索服務器,其實就是對Lucene
進行封裝,提供了REST
API 的操作接口。
ElasticSearch
作為一個高度可拓展的開源全文搜索和分析引擎,可用於快速地對大數據進行存儲,搜索和分析。
ElasticSearch
主要特點:分佈式、高可用、異步寫入、多API、面向文檔 。
ElasticSearch
核心概念:近實時,集群,節點(保存數據),索引,分片(將索引分片),副本(分片可設置多個副本) 。它可以快速地儲存、搜索和分析海量數據。
Docker搭建 Elasticsearch
安裝Elasticsearch的Docker鏡像
目前Elasticsearch 版本到了7.X, Springboot 目前不支持7.X以上的elasticsearch。所以還是選擇了穩定的2.4.6
ubuntu@VM-0-5-ubuntu:~$ docker pull elasticsearch:2.4.6 2.4.6: Pulling from library/elasticsearch 05d1a5232b46: Already exists 5cee356eda6b: Already exists 89d3385f0fd3: Already exists 65dd87f6620b: Already exists 78a183a01190: Already exists 1a4499c85f97: Already exists 2c9d39b4bfc1: Already exists 1b1cec2222c9: Already exists 59ff4ce9df68: Already exists 1976bc3ee432: Already exists a27899b7a5b5: Already exists b0fc7d2c927a: Already exists 6d94b96bbcd0: Already exists 6f5bf40725fd: Already exists 2bf2a528ae9a: Already exists Digest: sha256:41ed3a1a16b63de740767944d5405843db00e55058626c22838f23b413aa4a39 Status: Downloaded newer image for elasticsearch:2.4.6 docker.io/library/elasticsearch:2.4.6 ubuntu@VM-0-5-ubuntu:~$ docker run -d -p 9200:9200 -p 9300:9300 --name elasticsearch elasticsearch:2.4.6 # 如果跑不了,與服務器的內存有關 ubuntu@VM-0-5-ubuntu:~$ docker run -e ES_JAVA_OPIS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name elasticsearch elasticsearch:2.4.6 4e54a696130f92c7a94835313a36e359e51cf02f08e85fc281667e4a238cf5e9
訪問服務器的9200端口,測試是否成功搭建Elasticsearch

springboot搭建 Elasticsearch工程
選擇NOSQL中的 Elasticsearch
依賴

pom.xml項目配置依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
SpringBoot默認支持兩種技術來和ES交互
- Jest(默認不生效)
需要導入jest的工具包(io.searchbox.client.JestClient)
- SpringData ElasticSearch【ES版本有可能不合適】
Jest
Jest是Elasticsearch 的Java Http Rest 客戶端。
ElasticSearch已經具備應用於Elasticsearch內部的Java API,但是Jest彌補了ES自有API缺少Elasticsearch Http Rest接口客戶端的不足。
去maven倉庫搜jest
鏈接: https://mvnrepository.com/artifact/io.searchbox/jest

記得在pom文件中引入jest,先注釋掉ElasticSearch的依賴:
<!-- <dependency>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>--> <!-- </dependency>--> <!-- https://mvnrepository.com/artifact/io.searchbox/jest --> <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>2.4.0</version> </dependency>
Jest
使用默認配置JestAutoConfiguration
,而JestAutoConfiguration
注入一個JestClient
,要使用這個客戶端,要先在配置文件中指定es的地址:
application.properties配置文件
spring.elasticsearch.jest.uris=http://ip:9200
跑起來看看是否連接成功

Jest實戰演練
創建bean.Article
類,私有變量id
, author
,title
,content
,補充Getter和Setter
@JestId
import io.searchbox.annotations.JestId; /** * @author: 毛利 */ public class Article { @JestId private Integer id; private String author; private String title; private String content; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }

ElasticsearchApplicationTests
測試類中

@Autowired JestClient jestClient; @Test void contextLoads() { // 給Es中索引(保存)一個文檔; Article article = new Article(); article.setId(1); article.setTitle("好消息"); article.setAuthor("zhangsan"); article.setContent("Hello World"); // 構建一個索引功能 Index index = new Index.Builder(article).index("atguigu").type("news").build(); try { jestClient.execute(index); } catch (IOException e) { e.printStackTrace(); } }
運行測試,訪問http://ip:9200/atguigu/news/1

測試搜索
@Test void search() { //查詢表達式 content有hello String json = "{n" + " "query" : {n" + " "match" : {n" + " "content" : "hello"n" + " }n" + " }n" + "}"; //構建搜索功能 Search search = new Search.Builder(json).addIndex("atguigu").addType("news").build(); //執行 try { SearchResult result = jestClient.execute(search); System.out.println(result.getJsonString()); } catch (IOException e) { e.printStackTrace(); } }
更多操作:https://github.com/searchbox-io/Jest/tree/master/jest
測試運行

運行如下
SpringData ElasticSearch
還有一個SpringData ElasticSearch
pom文件打開SpringData ElasticSearch
依賴
注意Elasticsearch
和spring-boot-starter-data-elasticsearch
版本對應

新新版本的SpringBoot 2
的spring-boot-starter-data-elasticsearch
中支持的Elasticsearch
版本是2.X, 但Elasticsearch
實際上已經發展到6.5.X版本了,為了更好的使用Elasticsearch
的新特性, 所以棄用了spring-boot-starter-data-elasticsearch
依賴,而改為直接使用Spring-data-elasticsearch

Docker安裝Elasticsearch鏡像6.X,和上面一樣
docker pull elasticsearch:6.8.6 # 加速 docker pull registry.docker-cn.com/library/elasticsearch:6.8.6 docker run -d -p 9201:9200 -p 9301:9300 --name elasticsearch elasticsearch:6.8.6 # 我發現內存空間不夠,好像很多人死在那 docker run --name elasticsearch -d -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -e "discovery.type=single-node" -p 9201:9200 -p 9301:9300 elasticsearch:6.8.6

訪問測試OK
docker-cluster
這裡創建一個容器變了
application.properties配置文件
spring.data.elasticsearch.cluster-name=docker-cluster spring.data.elasticsearch.cluster-nodes=ip:9301
跑起來測試下

SpringData ElasticSearch就是編寫一個ElasticsearchRepository
的子接口來操作ES
SpringData ElasticSearch實戰演練
新建bean.Book類,三個類變量,補充Getter
和Setter
ElasticSearch是面對文檔的
@Document(indexName = "atguigu", type = "book")
補充文檔:index序列和type

import org.springframework.data.elasticsearch.annotations.Document; /** * @author: 毛利 */ @Document(indexName = "atguigu", type = "book") public class Book { private Integer id; private String bookName; private String author; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "Book{" + "id=" + id + ", bookName='" + bookName + ''' + ", author='" + author + ''' + '}'; } }
編寫repository.BookRepository接口繼承ElasticsearchRepository
接口

同時重寫findByBookNameLike`方法
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * @author: 毛利 */ public interface BookRepository extends ElasticsearchRepository<Book, Integer> { public List<Book> findByBookNameLike(String bookName); }
測試類
@Autowired BookRepository bookRepository; @Test public void test02() { Book book = new Book(); book.setId(1); book.setBookName("西遊記"); book.setAuthor("吳承恩"); bookRepository.index(book); }
運行測試類後,訪問是否找到book1


@Test public void test02() { // Book book = new Book(); // book.setId(1); // book.setBookName("西遊記"); // book.setAuthor("吳承恩"); // bookRepository.index(book); // 測試是否通過findByBookNameLike的模糊查詢找到西遊記 for (Book book : bookRepository.findByBookNameLike("游")) { System.out.println(book); } }

總結
本文通過兩種方法實現對Springboot
整合ElasticSearch
希望以上對你學習有用
再自我介紹一下吧。我叫潤森,是一個的學習者。