本章介绍SpringBoot与ElasticSearch整合,SpringBoot默认支持两种技术来与ES交互
1、Jest(默认不生效,需要导入jest工具包)
2、SpringBoot ElasticSearch(ES版本可能不合适,需要相应版本)
ElasticSearch安装参考:【ElasticSearch】 安装
ElasticSearch自动配置
1、搭建SpringBoot项目,pom.xml文件如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.test</groupId> 8 <artifactId>test-springboot-es</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>2.1.8.RELEASE</version> 15 </parent> 16 17 <properties> 18 19 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 20 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 21 <java.version>1.8</java.version> 22 </properties> 23 24 <dependencies> 25 26 <dependency> 27 <groupId>org.springframework.boot</groupId> 28 <artifactId>spring-boot-starter-web</artifactId> 29 </dependency> 30 31 <!-- SpringBoot默认使用SpringData ElasticSearch模块进行操作 --> 32 <dependency> 33 <groupId>org.springframework.boot</groupId> 34 <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 35 </dependency> 36 37 <!-- https://mvnrepository.com/artifact/io.searchbox/jest --> 38 <!--<dependency>--> 39 <!--<groupId>io.searchbox</groupId>--> 40 <!--<artifactId>jest</artifactId>--> 41 <!--<version>6.3.1</version>--> 42 <!--</dependency>--> 43 44 <dependency> 45 <groupId>org.springframework.boot</groupId> 46 <artifactId>spring-boot-starter-test</artifactId> 47 <scope>test</scope> 48 </dependency> 49 50 </dependencies> 51 52 53 <!-- SpringBoot打包插件,可以将代码打包成一个可执行的jar包 --> 54 <build> 55 <plugins> 56 <plugin> 57 <groupId>org.springframework.boot</groupId> 58 <artifactId>spring-boot-maven-plugin</artifactId> 59 </plugin> 60 </plugins> 61 </build> 62 </project>
2、查看spring-boot-autoconfigure中,在org.springframework.boot.autoconfigure.data.elasticsearch包下有很多Elasticsearch自动配置类,可以分别查看,可以看到注入了对象,其中有ElasticsearchRepositoriesAutoConfiguration、ElasticsearchDataAutoConfiguration等
3、启动ElasticsearchDataAutoConfiguration类中,自动注入了ElasticsearchTemplate,用于操作Elasticsearch
1 public class ElasticsearchDataAutoConfiguration { 2 3 @Bean 4 @ConditionalOnMissingBean 5 @ConditionalOnBean(Client.class) 6 public ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) { 7 try { 8 return new ElasticsearchTemplate(client, converter); 9 } 10 catch (Exception ex) { 11 throw new IllegalStateException(ex); 12 } 13 } 14 15 ... 16 }
4、查看spring-boot-autoconfigure中,在org.springframework.boot.autoconfigure.elasticsearch.jest包下,有JestAutoConfiguration自动配置类,它给SpringBoot自动注入了JestClient也是用来操作Elasticsearch的
1 public class JestAutoConfiguration { 2 3 ... 4 5 @Bean(destroyMethod = "shutdownClient") 6 @ConditionalOnMissingBean 7 public JestClient jestClient() { 8 JestClientFactory factory = new JestClientFactory(); 9 factory.setHttpClientConfig(createHttpClientConfig()); 10 return factory.getObject(); 11 } 12 13 ... 14 }
SpringBoot整合Jest
1、在SpringBoot项目中,引入Jest依赖
1 <dependency> 2 <groupId>io.searchbox</groupId> 3 <artifactId>jest</artifactId> 4 <version>6.3.1</version> 5 </dependency>
2、添加jest的es配置信息
spring: elasticsearch: jest: uris: http://192.168.0.1:9200
3、编写测试类,测试jest,内容如下:
1 package com.test.springboot.es; 2 3 import com.test.springboot.es.bean.Article; 4 import io.searchbox.client.JestClient; 5 import io.searchbox.core.Index; 6 import io.searchbox.core.Search; 7 import io.searchbox.core.SearchResult; 8 import org.junit.Test; 9 import org.junit.runner.RunWith; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.boot.test.context.SpringBootTest; 12 import org.springframework.test.context.junit4.SpringRunner; 13 14 import java.io.IOException; 15 16 @RunWith(SpringRunner.class) 17 @SpringBootTest 18 public class TestApplication { 19 20 @Autowired 21 JestClient jestClient; 22 23 // 给ES索引(保存)一个文档 24 @Test 25 public void contextLoad() throws IOException { 26 Article article = new Article(); 27 article.setId(1); 28 article.setTitle("好消息"); 29 article.setAuthor("张三"); 30 article.setContent("Hello Word"); 31 32 // 构建一个索引功能 33 Index index = new Index.Builder(article).index("test").type("news").build(); 34 // 执行 35 jestClient.execute(index); 36 } 37 38 // 测试Jest搜索 39 @Test 40 public void jestSearch() throws IOException { 41 42 String json = "{\n" + 43 " \"query\" : {\n" + 44 " \"match\" : {\n" + 45 " \"content\" : \"Hello\"\n" + 46 " }\n" + 47 " }\n" + 48 "}"; 49 50 // 构建一个搜索功能 51 Search search = new Search.Builder(json).addIndex("test").addType("news").build(); 52 // 执行 53 SearchResult result = jestClient.execute(search); 54 // 打印结果 55 System.out.println(result.getJsonString()); 56 } 57 }
4、测试方法
运行方法contextLoad(),保存数据,使用地址(http://192.168.0.1:9200/test/news/_search)访问ElasticSearch,获得数据如下:
运行jestSearch() 方法,测试Jest搜索,效果如下:
5、更多jestClient,可以参考官方文档:https://github.com/searchbox-io/Jest/tree/master/jest
SpringBoot整合ElasticSearch
1、在SpringBoot项目中,引入依赖spring-boot-starter-data-elasticsearch,版本问题参考官网:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.0.M4/reference/html/#preface.versions
1 <!-- SpringBoot默认使用SpringData ElasticSearch模块进行操作 --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 5 </dependency>
2、添加elasticsearch的配置信息
spring: data: elasticsearch: #集群名称 cluster-name: elasticsearch #节点 cluster-nodes: 192.168.0.1:9300
注:其中节点的端口使用的是9300端口,也就是ES节点之间通讯使用的端口。
3、编辑方法save(),保存数据到elasticsearch中,内容如下:
1 @RunWith(SpringRunner.class) 2 @SpringBootTest 3 public class TestApplication2 { 4 5 @Autowired 6 ElasticsearchTemplate elasticsearchTemplate; 7 8 // 给ES索引(保存)一个文档 9 @Test 10 public void save() { 11 Article article = new Article(); 12 article.setId(1); 13 article.setTitle("好消息"); 14 article.setAuthor("张三"); 15 article.setContent("Hello Word"); 16 17 IndexQuery indexQuery = new IndexQueryBuilder() 18 .withId(article.getId().toString()) 19 .withObject(article) 20 .build(); 21 22 // 存入索引,返回文档ID 23 String documentId = elasticsearchTemplate.index(indexQuery); 24 System.out.println(documentId); 25 26 } 27 }
注意Article类需要进行文档注释,内容如下,否则报错
1 @Document(indexName="test", type = "news") 2 public class Article { 3 4 private Integer id; 5 private String author; 6 private String title; 7 private String content; 8 }
4、测试方法save(),运行save()方法后,使用浏览器访问es,地址:http://192.168.0.1:9200/test/news/1
5、编辑方法search(),查询数据
1 // 测试elasticsearchTemplate搜索 2 @Test 3 public void search() throws IOException { 4 5 String json = "{\n" + 6 " \"match\" : {\n" + 7 " \"content\" : \"Hello\"\n" + 8 " }\n" + 9 " }"; 10 11 StringQuery query = new StringQuery(json); 12 query.addIndices("test"); 13 query.addTypes("news"); 14 15 List<Article> articles = elasticsearchTemplate.queryForList(query, Article.class); 16 if(articles.size() > 0) { 17 for (Article a : articles){ 18 System.out.println(a.toString()); 19 } 20 } 21 }
6、执行方法search(),结果如下:
Spring Data Repositories功能
参考文档:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.0.M4/reference/html/#repositories
编写一个ElasticsearchRepository的子接口来操ES
7、编写ElasticsearchRepository的子接口,无需使用@Repository注解,SpringBoot会自动注入容器
1 package com.test.springboot.es.bean.repository; 2 3 import com.test.springboot.es.bean.Article; 4 import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 6 public interface ArticleRepository extends ElasticsearchRepository<Article, Integer> { 7 }
8、编写测试方法,测试ArticleRepository类的保存
1 @Autowired 2 ArticleRepository articleRepository; 3 4 @Test 5 public void test01(){ 6 Article article = new Article(); 7 article.setId(2); 8 article.setTitle("慢消息"); 9 article.setAuthor("李四"); 10 article.setContent("Hello XXXX"); 11 12 articleRepository.save(article); 13 14 }
9、运行方法test01(),之后查询索引test,地址:http://192.168.0.1:9200/test/news/_search
10、自定义查询方法,在ArticleRepository类中,增加findByAuthor方法
1 public interface ArticleRepository extends ElasticsearchRepository<Article, Integer> { 2 3 List<Article> findByAuthor(String author); 4 5 }
11、编辑测试方法forindByAuthor()
1 @Test 2 public void forindByAuthor(){ 3 List<Article> articles = articleRepository.findByAuthor("李四"); 4 if(articles.size() > 0) { 5 for (Article a : articles){ 6 System.out.println(a.toString()); 7 } 8 } 9 }
12、测试自定义查询方法