SpringBoot 整合 elasticsearch

程式設計師果果發表於2019-02-28

一、簡介

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

二、安裝elasticsearch

我們採用 docker映象安裝的方式。

#下載映象
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 如下圖,說明安裝成功

SpringBoot 整合 elasticsearch

三、elasticsearch的一些概念

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

SpringBoot 整合 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

<?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的文件:github.com/searchbox-i…

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

	}

}

複製程式碼

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

SpringBoot 整合 elasticsearch

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

SpringBoot 整合 elasticsearch

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

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

SpringBoot 整合 elasticsearch

叢集名為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,可以得到我們存入的索引資訊。

SpringBoot 整合 elasticsearch

原始碼下載:github.com/gf-huanchup…

SpringBoot 整合 elasticsearch

相關文章