原創 | 一篇解決Springboot 整合 Elasticsearch

  • 2020 年 1 月 14 日
  • 筆記

大家好,我是潤森。期末已掛,誰來燒紙。

昨天我發現IDEA過期了,十分鐘解決了。公眾號回復 IDEA就ok

ElasticSearch

結合業務的場景,在目前的商品體系需要構建搜索服務,主要是為了提供用戶更豐富的檢索場景以及高速,實時及性能穩定的搜索服務。

ElasticSearch是一個基於Lucene的搜索服務器,其實就是對Lucene進行封裝,提供了RESTAPI 的操作接口。

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交互

  1. Jest(默認不生效)

需要導入jest的工具包(io.searchbox.client.JestClient)

  1. 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依賴

注意Elasticsearchspring-boot-starter-data-elasticsearch版本對應

新新版本的SpringBoot 2spring-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類,三個類變量,補充GetterSetter

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

希望以上對你學習有用

再自我介紹一下吧。我叫潤森,是一個的學習者。