一 ElasticSearch与检索
二 搭建环境
1、搭建SpringBoot项目,pom.xml文件如下:
<!-- SpringBoot默认使用SpringData ElasticSearch模块进行操作 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
2、查看spring-boot-autoconfigure中,在org.springframework.boot.autoconfigure.data.elasticsearch包下有很多Elasticsearch自动配置类,可以分别查看,可以看到注入了对象,其中有ElasticsearchRepositoriesAutoConfiguration、ElasticsearchDataAutoConfiguration等
3、启动ElasticsearchDataAutoConfiguration类中,自动注入了ElasticsearchTemplate,用于操作Elasticsearch
public class ElasticsearchDataAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(Client.class)
public ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) {
try {
return new ElasticsearchTemplate(client, converter);
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
...
}
4、查看spring-boot-autoconfigure中,在org.springframework.boot.autoconfigure.elasticsearch.jest包下,有JestAutoConfiguration自动配置类,它给SpringBoot自动注入了JestClient也是用来操作Elasticsearch的
public class JestAutoConfiguration {
...
@Bean(destroyMethod = "shutdownClient")
@ConditionalOnMissingBean
public JestClient jestClient() {
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(createHttpClientConfig());
return factory.getObject();
}
...
}
SpringBoot与ElasticSearch整合,SpringBoot默认支持两种技术来与ES交互
1、Jest(默认不生效,需要导入jest工具包)
2、SpringBoot ElasticSearch(ES高版本可能不合适,需要相应版本)
三、SpringBoot整合Jest
1、在SpringBoot项目中,引入Jest依赖
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>6.3.1</version>
</dependency>
2、添加jest的es配置信息
spring:
elasticsearch:
jest:
uris: http://192.168.0.1:9200
3、编写测试类,测试jest,内容如下:
package com.test.springboot.es;
import com.test.springboot.es.bean.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 TestApplication {
@Autowired
JestClient jestClient;
// 给ES索引(保存)一个文档
@Test
public void contextLoad() throws IOException {
Article article = new Article();
article.setId(1);
article.setTitle("好消息");
article.setAuthor("张三");
article.setContent("Hello Word");
// 构建一个索引功能
Index index = new Index.Builder(article).index("test").type("news").build();
// 执行
jestClient.execute(index);
}
// 测试Jest搜索
@Test
public void jestSearch() throws IOException {
String json = "{\n" +
" \"query\" : {\n" +
" \"match\" : {\n" +
" \"content\" : \"Hello\"\n" +
" }\n" +
" }\n" +
"}";
// 构建一个搜索功能
Search search = new Search.Builder(json).addIndex("test").addType("news").build();
// 执行
SearchResult result = jestClient.execute(search);
// 打印结果
System.out.println(result.getJsonString());
}
}
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
<!-- SpringBoot默认使用SpringData ElasticSearch模块进行操作 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
spring:
data:
elasticsearch:
#集群名称
cluster-name: elasticsearch
#节点
cluster-nodes: 192.168.0.1:9300
注:其中节点的端口使用的是9300端口,也就是ES节点之间通讯使用的端口。
elasticsearchTemplate操作es
1、编辑方法save(),保存数据到elasticsearch中,内容如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplication2 {
@Autowired
ElasticsearchTemplate elasticsearchTemplate;
// 给ES索引(保存)一个文档
@Test
public void save() {
Article article = new Article();
article.setId(1);
article.setTitle("好消息");
article.setAuthor("张三");
article.setContent("Hello Word");
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(article.getId().toString())
.withObject(article)
.build();
// 存入索引,返回文档ID
String documentId = elasticsearchTemplate.index(indexQuery);
System.out.println(documentId);
}
}
注意Article类需要进行文档注释,内容如下,否则报错
@Document(indexName="test", type = "news")
public class Article {
private Integer id;
private String author;
private String title;
private String content;
}
2、测试方法save(),运行save()方法后,使用浏览器访问es,地址:http://192.168.0.1:9200/test/news/1
3、编辑方法search(),查询数据
// 测试elasticsearchTemplate搜索
@Test
public void search() throws IOException {
String json = "{\n" +
" \"match\" : {\n" +
" \"content\" : \"Hello\"\n" +
" }\n" +
" }";
StringQuery query = new StringQuery(json);
query.addIndices("test");
query.addTypes("news");
List<Article> articles = elasticsearchTemplate.queryForList(query, Article.class);
if(articles.size() > 0) {
for (Article a : articles){
System.out.println(a.toString());
}
}
}
4、执行方法search(),结果如下:
Spring Data Repositories操作es
编写一个ElasticsearchRepository的子接口来操ES
1、编写ElasticsearchRepository的子接口,无需使用@Repository注解,SpringBoot会自动注入容器
package com.test.springboot.es.bean.repository;
import com.test.springboot.es.bean.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface ArticleRepository extends ElasticsearchRepository<Article, Integer> {
}
2、编写测试方法,测试ArticleRepository类的保存
@Autowired
ArticleRepository articleRepository;
@Test
public void test01(){
Article article = new Article();
article.setId(2);
article.setTitle("慢消息");
article.setAuthor("李四");
article.setContent("Hello XXXX");
articleRepository.save(article);
}
3、运行方法test01(),之后查询索引test,地址:http://192.168.0.1:9200/test/news/_search
4、自定义查询方法,在ArticleRepository类中,增加findByAuthor方法
public interface ArticleRepository extends ElasticsearchRepository<Article, Integer> {
List<Article> findByAuthor(String author);
}
5、编辑测试方法forindByAuthor()
@Test
public void forindByAuthor(){
List<Article> articles = articleRepository.findByAuthor("李四");
if(articles.size() > 0) {
for (Article a : articles){
System.out.println(a.toString());
}
}
}
6、测试自定义查询方法