文章目录
十四、Spring Boot与检索
1、检索简述
我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;
Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用了ElasticSearch作为其搜索服务,
Elasticsearch 是面向文档的,意味着它存储整个对象或 文档。Elasticsearch不仅存储文档,而且 索引每个文档的内容使之可以被检索。在 Elasticsearch 中,你对文档进行索引、检索、排序和过滤–而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。
2、搭建环境
[root@localhost ~]# docker pull registry.docker-cn.com/library/elasticsearch
[root@localhost ~]# docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name ES01 5acf0e8da90b
c2a8a49519b42a3035bab87d6107464aa5e83e4ae9fea06eed0545f7b7504a55
ES启动默认会占用2G的运行内存,因此需要手动去修改最小和最大占用内存,不然虚拟机会宕机
3、概念
以员工文档的形式存储为例:一个文档代表一个员工数据。存储数据到 ElasticSearch的行为叫做 索引,但在索引一个文档之前,需要确定将文档存储在哪里。
一个 ElasticSearch 集群可以包含多个 索引 ,相应的每个索引可以包含多个类型 。这些不同的类型存储着多个文档 ,每个文档又有多个 属性 。
类似关系:
索引-数据库
类型-表
文档-表中的记录
属性-列
4、整合ElasticSearch测试
<1>、搭建环境
在application.properties中配置ES端口号
spring.elasticsearch.jest.uris=http://192.168.3.158:9200
<2>、ES交互
SpringBoot默认使用俩种规则进行交互
(1)、Jest(默认不生效)
需要导入Jest工具包(io.searchbox.client.JestClient)
导入Jest相关的maven配置程序,然后将SpringData的maven打上注释
<!-- https://mvnrepository.com/artifact/io.searchbox/jest -->
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>5.3.3</version>
</dependency>
ES是5.6.12版本,所以Jest的版本也应该是5.X
为ES索引一个文档,方便操作
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;
}
}
为我们的ES文档创建一个索引
@Autowired
JestClient jestClient;
@Test
public void contextLoads() {
//1、给Es索引中(保存)一个文档
Article article = new Article();
article.setId(1);
article.setAuthor("zpw");
article.setTitle("好消息");
article.setContent("Love Forever");
//构建一个索引功能
Index index = new Index.Builder(article).index("atguigu").type("news").build();
try {
//执行操作
jestClient.execute(index);
} catch (IOException e) {
e.printStackTrace();
}
}
使用Jest来进行一下搜索数据的操作
@Test
public void receive(){
String json = "{\n" +
"\t\"query\" : {\n" +
"\t\t\"match\" :{\n" +
"\t\t\t\"content\" : \"hello\"\n" +
"\t\t}\n" +
"\t}\n" +
"}";
Search search = new Search.Builder(json).addIndex("atguigu").addType("news").build();
try {
SearchResult searchResult = jestClient.execute(search);
System.out.println(searchResult.getJsonString());
} catch (IOException e) {
e.printStackTrace();
}
}
(2)、SpringData ElasticSearch
将原来的SpringData的注释消除,在pom中引入相关依赖并且在application.properties中配置ElasticSearch的相关配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=192.168.3.158:9300
运行,出现版本不适配的问题,显示连接拒绝。
解决方法有两个,第一个就是提升SpringBoot的版本,第二就是降低ES的版本。
这里选择第二个,
ES使用的是2.4.6,来到Docker中下载2.4.6版本的ElasticSearch,操作步骤省略
Properties的端口号也改成9301,重新运行,成功。
1、Client 节点信息clusterNodes;clusterName
2、ElasticSearchTemplate来操作ES
3、编写一个ElasticSearchRepository的子接口来操作ES
编写一个BookRepository
首先创建一个接口
public interface BookRepository extends ElasticsearchRepository{
}
内部需要俩个泛型,是和操作的数据源相关的,所以先创建数据源。
@Document(indexName = "example", 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;
}
}
Book是被定义为文档的,需要加上Document的注解,然后声明类型和索引,就可以返回我们的接口类,重新编写接口
public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
//自定义一个查询方法
//其他方法参照 https://docs.soring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/
List<Book> findByBookNameLike(String bookName);
}
Book是要操作的主键,Integer是主键类型。
测试:
@Autowired
BookRepository bookRepository;
@Test
public void test01(){
// Book book = new Book();
// book.setId(1);
// book.setBookName("西游记");
// book.setAuthor("吴承恩");
// bookRepository.index(book);
List<Book> bookList = bookRepository.findByBookNameLike("记");
for (Book book : bookList){
System.out.println(book);
}
}
运行成功:
{"_index":"example","_type":"book","_id":"1","found":false}