#1、Elasticsearch简介
我们的应用经常需要添加检索功能,更或者是大量日志检索分析等,Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;
Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用了Elasticsearch作为其搜索服务;
1.1 相关的概念
以员工文档的形式存储为例:一个文档代表一个员工数据。存储数据到Elasticsearch 的行为叫做索引,但在索引一个文档之前,需要确定将文档存储在哪里。
- 一个Elasticsearch 集群可以包含多个索引,相应的每个索引可以包含多个类型。这些不同的类型存储着多个文档,每个文档又有多个属性
- 类似MySQL的关系:
索引—数据库
类型—表
文档—表中的记录
属性—列
参考官方指南:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
2、安装Elasticsearch
Spring Data ElasticsearchSpr | Elasticsearch |
3.2.x | 6.7.2 |
3.1.x | 6.2.2 |
3.0.x | 5.5.0 |
2.1.x | 2.4.0 |
2.0.x | 2.2.0 |
1.3.x | 1.5.2 |
而我们使用的是2.2.6的SpringBoot版本,它对应的Spring Data Elasticsearch的版本是3.2.6,所以Elasticsearch要按照6.7.2及以上的,而我们导入的es的jar包是6.8.7 ,所以我们就拉取6.8.7的镜像
使用docker来安装Elasticsearch:
- docker search elasticsearch:搜索镜像
- docker pull elasticsearch:6.8.7:拉取镜像
ElasticSearch默认启动会占用两个G的内存,所以启动的时候,需要使用 -e ES_JAVA_OPTS="-Xms256m -Xmx256m" 来限制占用的内存大小;
- docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name ES01 5acf0e8da90b:运行镜像(9200是浏览器访问端口,9300是Java访问端口)
浏览器访问:http://10.254.14.56:9200/ ,能看到下面的信息就说明成功了:
name "ckaUxfg"
cluster_name "docker-cluster"
cluster_uuid "5Rj6tcpTTDqQFYPNTtJqAg"
version
number "6.8.7"
build_flavor "default"
build_type "docker"
build_hash "c63e621"
build_date "2020-02-26T14:38:01.193138Z"
build_snapshot false
lucene_version "7.7.2"
minimum_wire_compatibility_version "5.6.0"
minimum_index_compatibility_version "5.0.0"
tagline "You Know, for Search"
如果访问不成功,docker ps -a 可以看到启动就退出了,就可以尝试下面的操作:
- 修改配置文件:vi /etc/sysctl.conf
- 添加下面配置:vm.max_map_count=655360
- 并执行命令:sysctl -p
然后要docker rm 容器id,先删除容器,再执行docker run重新启动,浏览器访问:http://10.254.14.56:9200/
3、SpringBoot整合Elasticsearch
使用SpringBoot的向导创建项目,选中web模块和Spring Data Elasticsearch模块:
Spring Data Elasticsearch和elasticsearch的版本对应关系:
Spring Data Elasticsearch | Elasticsearch |
3.2.x | 6.7.2 |
3.1.x | 6.2.2 |
3.0.x | 5.5.0 |
2.1.x | 2.4.0 |
2.0.x | 2.2.0 |
1.3.x | 1.5.2 |
如果版本不对应,执行的时候会报错:NoNodeAvailableException[None of the configured nodes are available
3.1 pom文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springboot.es</groupId>
<artifactId>springboot-03-es</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-03-es</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
##3.2 application.properties
配置:Client 节点信息clusterNodes;clusterName
spring.data.elasticsearch.cluster-name=docker-cluster
spring.data.elasticsearch.cluster-nodes=192.168.0.103:9300
注意:spring.data.elasticsearch.cluster-name=docker-cluster 对应的是我们浏览器访问 http://10.254.14.56:9200/ 的cluster_name,默认是elasticsearch,这个好像根据版本不同有差别,要注意。
3.3 定义book类
package com.springboot.es.bean;
import org.springframework.data.elasticsearch.annotations.Document;
import java.util.Date;
/**
* @Document:表明这是一个Elasticsearch的一个文档类
* indexName指定索引名称
* type:指定类型名称
*/
@Document(indexName = "zxh",type = "book")
public class Book {
private Integer id;
private String name;
private boolean isSuccess;
private Date publishDate;
public Book() {//无参构造不能省
}
public Book(Integer id, String name, boolean isSuccess, Date publishDate) {
this.id = id;
this.name = name;
this.isSuccess = isSuccess;
this.publishDate = publishDate;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", isSuccess=" + isSuccess +
", publishDate=" + publishDate +
'}';
}
//get/set方法
}
- @Document:表明这是一个Elasticsearch的一个文档类:indexName指定索引名称,type:指定类型名称
##3.4 测试
3.4.1 方式一:继承ElasticsearchRepository接口
定义个接口:
- 类似JPA的开发方式,编写一个继承 ElasticsearchRepository 的子接口,其他地方就能注入它
- 并且拥有了分页以及增删改查功能了,同时也支持像JPA那样的自定义方法,但是不用写任何的实现
- ElasticsearchRepository 的第一个泛型是 JavaBean的类型,第二个泛型是主键类型
package com.springboot.es.repository;
import com.springboot.es.bean.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
/**
* 类似JPA的开发方式,编写一个继承 ElasticsearchRepository 的子接口,其他地方就能注入它
* 并且拥有了分页以及增删改查功能了,同时也支持像JPA那样的自定义方法,但是不用写任何的实现
* ElasticsearchRepository 的第一个泛型是 JavaBean的类型,第二个泛型是主键类型
*/
public interface BookElasticsearch extends ElasticsearchRepository<Book,Integer> {
Book findBookByNameLike(String name);
}
使用:
import com.springboot.es.bean.Book;
import com.springboot.es.repository.BookElasticsearch;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Client;
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.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot03EsApplicationTests {
@Autowired
BookElasticsearch bookElasticsearch;
//测试往es索引文档
@Test
public void contextLoads() {
bookElasticsearch.index(new Book(1001,"zdw的elasticsearch",true,new Date()));
}
//测试从 es索引文档
@Test
public void getIndex() {
/*Book book = new Book();
book.setId(1001);
Book save = bookElasticsearch.save(book);
System.out.println(save.getName()+"--"+book.getPublishDate());*/
Book zdw = bookElasticsearch.findBookByNameLike("zdw");
System.out.println(zdw);
}
}
3.4.2 方式二:使用ElasticsearchTemplate
直接使用@Autowired注入即可,SpringBoot已经帮我们配置了好,添加到了容器中:
@Autowired
ElasticsearchTemplate elasticsearchTemplate;
//测试往es索引文档
@Test
public void templateIndex() {
/*Integer documentId = 1001;
Book book = new Book();
book.setId(documentId);
book.setName("zdw的elasticsearch");
IndexQuery indexQuery = new IndexQueryBuilder().withId(book.getId()+"").withObject(book).build();
String index = elasticsearchTemplate.index(indexQuery);
System.out.println(index);*/
Client client = elasticsearchTemplate.getClient();
GetResponse response = client.prepareGet("zxh", "book", "1001").get();
System.out.println(response.getSource());
}
简单的整合完成,具体使用还需要参照官方文档,后续继续学习。