Spring Boot 整合 elasticsearch

一、簡介

我們的應用經常需要添加檢索功能,開源的 ElasticSearch 是目前全文搜索引擎的 首選。他可以快速的存儲、搜索和分析海量數據。Spring Boot通過整合Spring Data ElasticSearch為我們提供了非常便捷的檢索功能支持;Elasticsearch是一個分佈式搜索服務,提供Restful API,底層基於Lucene,採用 多shard(分片)的方式保證數據安全,並且提供自動resharding的功能,github 等大型的站點也是採用了ElasticSearch作為其搜索服務,

二、安裝elasticsearch

我們採用 docker鏡像安裝的方式。

<code>#下載鏡像docker pull elasticsearch#啟動鏡像,elasticsearch 啟動是會默認分配2G的內存 ,我們啟動是設置小一點,防止我們內存不夠啟動失敗#9200是elasticsearch 默認的web通信接口,9300是分佈式情況下,elasticsearch個節點通信的端口docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name es01 5c1e1ecfe33a/<code>

訪問 127.0.0.1:9200 如下圖,說明安裝成功


Spring Boot 整合 elasticsearch


三、elasticsearch的一些概念

  • 員工文檔 的形式存儲為例:一個文檔代表一個員工數據。存儲數據到 ElasticSearch 的行為叫做索引 ,但在索引一個文檔之前,需要確定將文檔存 儲在哪裡。
  • 一個 ElasticSearch 集群可以 包含多個索引 ,相應的每個索引可以包含多個類型。這些不同的類型存儲著多個文檔 ,每個文檔又有 多個 屬性
  • 類似關係:索引-數據庫類型-表文檔-表中的記錄 – 屬性-列


Spring Boot 整合 elasticsearch


elasticsearch使用可以參早官方文檔,在這裡不在講解。

四、整合 elasticsearch

創建項目 springboot-elasticsearch,引入web支持 SpringBoot 提供了兩種方式操作elasticsearch,Jest 和 SpringData。

Jest 操作 elasticsearch

Jest是ElasticSearch的Java HTTP Rest客戶端。

ElasticSearch已經有一個Java API,ElasticSearch也在內部使用它,但是Jest填補了空白,它是ElasticSearch Http Rest接口缺少的客戶端。

1. pom.xml

<code><project>    <modelversion>4.0.0/<modelversion>    <groupid>com.gf/<groupid>    <artifactid>springboot-elasticsearch/<artifactid>    <version>0.0.1-SNAPSHOT/<version>    <packaging>jar/<packaging>    <name>springboot-elasticsearch/<name>    <description>Demo project for Spring Boot/<description>    <parent>        <groupid>org.springframework.boot/<groupid>        <artifactid>spring-boot-starter-parent/<artifactid>        <version>2.1.1.RELEASE/<version>        <relativepath>     /<parent>    <properties>        <project.build.sourceencoding>UTF-8/<project.build.sourceencoding>        <project.reporting.outputencoding>UTF-8/<project.reporting.outputencoding>        <java.version>1.8/<java.version>    /<properties>    <dependencies>        <dependency>        <groupid>org.springframework.boot/<groupid>        <artifactid>spring-boot-starter-data-elasticsearch/<artifactid>    /<dependency>        <dependency>            <groupid>io.searchbox/<groupid>            <artifactid>jest/<artifactid>            <version>5.3.3/<version>        /<dependency>        <dependency>            <groupid>org.springframework.boot/<groupid>            <artifactid>spring-boot-starter-web/<artifactid>        /<dependency>        <dependency>            <groupid>org.springframework.boot/<groupid>            <artifactid>spring-boot-starter-test/<artifactid>            <scope>test/<scope>        /<dependency>    /<dependencies>    <build>        <plugins>            <plugin>                <groupid>org.springframework.boot/<groupid>                <artifactid>spring-boot-maven-plugin/<artifactid>            /<plugin>        /<plugins>    /<build>/<project>/<code>

2. application.properties

<code>spring.elasticsearch.jest.uris=http://127.0.0.1:9200/<code>

3. Article

<code>package com.gf.entity;import io.searchbox.annotations.JestId;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;    }    @Override    public String toString() {        final StringBuilder sb = new StringBuilder( "{\"Article\":{" );        sb.append( "\"id\":" )                .append( id );        sb.append( ",\"author\":\"" )                .append( author ).append( '\"' );        sb.append( ",\"title\":\"" )                .append( title ).append( '\"' );        sb.append( ",\"content\":\"" )                .append( content ).append( '\"' );        sb.append( "}}" );        return sb.toString();    }}/<code>

4. springboot測試類

<code>package com.gf;import com.gf.entity.Article;import io.searchbox.client.JestClient;import io.searchbox.core.Index;import io.searchbox.core.Search;import io.searchbox.core.SearchResult;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException;@RunWith(SpringRunner.class)@SpringBootTestpublic class SpringbootElasticsearchApplicationTests {    @Autowired    JestClient jestClient;    @Test    public void createIndex() {        //1. 給ES中索引(保存)一個文檔        Article article = new Article();        article.setId( 1 );        article.setTitle( "好消息" );        article.setAuthor( "張三" );        article.setContent( "Hello World" );        //2. 構建一個索引        Index index = new Index.Builder( article ).index( "gf" ).type( "news" ).build();        try {            //3. 執行            jestClient.execute( index );        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void search() {        //查詢表達式        String query = "{\\n" +                "    \"query\" : {\\n" +                "        \"match\" : {\\n" +                "            \"content\" : \"hello\"\\n" +                "        }\\n" +                "    }\\n" +                "}";        //構建搜索功能        Search search = new Search.Builder( query ).addIndex( "gf" ).addType( "news" ).build();        try {            //執行            SearchResult result = jestClient.execute( search );            System.out.println(result.getJsonString());        } catch (IOException e) {            e.printStackTrace();        }    }}/<code>

Jest的更多api ,可以參照github的文檔:https://github.com/searchbox-io/Jest

SpringData 操作 elasticsearch

1. application.properties

<code>spring.data.elasticsearch.cluster-name=elasticsearchspring.data.elasticsearch.cluster-nodes=127.0.0.1:9300/<code>

2. Book

<code>package com.gf.entity;@Document( indexName = "gf" , 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() {        final StringBuilder sb = new StringBuilder( "{\"Book\":{" );        sb.append( "\"id\":" )                .append( id );        sb.append( ",\"bookName\":\"" )                .append( bookName ).append( '\"' );        sb.append( ",\"author\":\"" )                .append( author ).append( '\"' );        sb.append( "}}" );        return sb.toString();    }    }/<code>

3. BookRepository

<code>package com.gf.repository;import com.gf.entity.Book;import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import java.util.List;public interface BookRepository extends ElasticsearchRepository<book>{    List<book> findByBookNameLike(String bookName);}/<book>/<book>/<code>

4. springboot 測試類

<code>package com.gf;import com.gf.entity.Article;import com.gf.entity.Book;import com.gf.repository.BookRepository;import io.searchbox.client.JestClient;import io.searchbox.core.Index;import io.searchbox.core.Search;import io.searchbox.core.SearchResult;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException;import java.util.List;@RunWith(SpringRunner.class)@SpringBootTestpublic class SpringbootElasticsearchApplicationTests {    @Autowired    BookRepository bookRepository;        @Test    public void createIndex2(){        Book book = new Book();        book.setId(1);        book.setBookName("西遊記");        book.setAuthor( "吳承恩" );        bookRepository.index( book );    }    @Test    public void useFind() {        List<book> list = bookRepository.findByBookNameLike( "遊" );        for (Book book : list) {            System.out.println(book);        }    }}/<book>/<code>

我們啟動測試 ,發現報錯 。


Spring Boot 整合 elasticsearch


這個報錯的原因是springData的版本與我elasticsearch的版本有衝突,下午是springData官方文檔給出的適配表。


Spring Boot 整合 elasticsearch


我們使用的springdata elasticsearch的 版本是3.1.3 ,對應的版本應該是6.2.2版本,而我們是的 elasticsearch 是 5.6.9,所以目前我們需要更換elasticsearch的版本為6.X

<code>docker pull elasticsearch:6.5.1docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name es02 鏡像ID/<code>

訪問127.0.0.1:9200


Spring Boot 整合 elasticsearch


集群名為docker-cluster,所以我們要修改application.properties的配置了

<code>spring.data.elasticsearch.cluster-name=docker-clusterspring.data.elasticsearch.cluster-nodes=127.0.0.1:9300/<code>

我們再次進行測試,測試可以通過了 。我們訪問http://127.0.0.1:9200/gf/book/1,可以得到我們存入的索引信息。


Spring Boot 整合 elasticsearch


源碼下載:https://github.com/gf-huanchupk/SpringBootLearning


分享到:


相關文章: