Spring Boot 整合 elasticsearch

1、簡介

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

2、安裝elasticsearch

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

#下載鏡像
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

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

3、elasticsearch的一些概念

  • 員工文檔 的形式存儲爲例:一個文檔表明一個員工數據。存儲數據到 ElasticSearch 的行爲叫作索引 ,但在索引一個文檔以前,須要肯定將文檔存 儲在哪裏。
  • 一個 ElasticSearch 集羣能夠 包含多個索引 ,相應的每一個索引能夠包含多個類型。這些不一樣的類型存儲着多個文檔 ,每一個文檔又有 多個 屬性
  • 相似關係:程序員

    • 索引-數據庫
    • 類型-表
    • 文檔-表中的記錄 – 屬性-列

elasticsearch使用能夠參早官方文檔,在這裏不在講解。github

4、整合 elasticsearch

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

Jest 操做 elasticsearch

Jest是ElasticSearch的Java HTTP Rest客戶端。spring

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

1. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <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/> <!-- lookup parent from repository -->
    </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>

2. application.properties

spring.elasticsearch.jest.uris=http://127.0.0.1:9200

3. Article

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();
    }


}

4. springboot測試類

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)
@SpringBootTest
public 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();
        }

    }

}

Jest的更多api ,能夠參照github的文檔:https://github.com/searchbox-io/Jest數據庫

SpringData 操做 elasticsearch

1. application.properties

spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

2. Book

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();
    }
    
}

3. BookRepository

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, Integer>{

    List<Book> findByBookNameLike(String bookName);

}

4. springboot 測試類

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)
@SpringBootTest
public 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);
        }

    }

}

咱們啓動測試 ,發現報錯 。

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

咱們使用的springdata elasticsearch的 版本是3.1.3 ,對應的版本應該是6.2.2版本,而咱們是的 elasticsearch 是 5.6.9,因此目前咱們須要更換elasticsearch的版本爲6.Xapache

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

訪問127.0.0.1:9200

集羣名爲docker-cluster,因此咱們要修改application.properties的配置了

spring.data.elasticsearch.cluster-name=docker-cluster
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

咱們再次進行測試,測試能夠經過了 。咱們訪問http://127.0.0.1:9200/gf/book/1,能夠獲得咱們存入的索引信息。

源碼

https://github.com/gf-huanchu...

歡迎掃碼或微信搜索公衆號《程序員果果》關注我,關注有驚喜~

相關文章
相關標籤/搜索