Spring Boot 整合 elasticsearch

32次阅读

共计 7453 个字符,预计需要花费 19 分钟才能阅读完成。

一、简介
我们的应用经常需要添加检索功能,开源的 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 如下图,说明安装成功

三、elasticsearch 的一些概念

以 员工文档 的形式存储为例: 一个文档代表一个员工数据。存储数据到 ElasticSearch 的行为叫做索引,但在索引一个文档之前,需要确定将文档存 储在哪里。
一个 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 的文档: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.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
集群名为 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…
关注我的公众号,精彩内容不能错过~

正文完
 0