SpringBoot整合Elasticsearch
elasticsearch中文文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
elasticsearch关键概念关系图
一、docker操作
拉取elasticsearch镜像
[root@localhost ~]# docker pull elasticsearch
查看拉取的elasticsearch镜像
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE elasticsearch latest 097d037f8ff8 9 days ago 486MB
创建并运行elasticsearch容器
-d表示后台启动;
-e ES_JAVA_OPTS="-Xms256m -Xmx256m"是设置elasticsearch使用的内存大小,默认是2G,-Xms256m是设置初始化时分配的内存大小是256M,-Xmx256m是设置最大可以使用的内存大小是256m;
-p是做端口映射,9200是elasticsearch进行web通信默认使用的端口,9300是分布式时elasticsearch各个节点之间通信时所使用的端口;
–name是为创建的elasticsearch容器取个名字;097d037f8ff8是elasticsearch镜像的id[root@localhost ~]# docker run -d -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -p 9200:9200 -p 9300:9300 --name ES01 097d037f8ff8
在window中的浏览器中输入http://192.168.0.114:9200,查看elasticsearch是否启动成功,192.168.0.114是linux服务器的ip地址,如果返回了下面类似的json串就表示elasticsearch启动成功了,并且是可以访问的
// 20180902162119 // http://192.168.0.114:9200/ { "name": "LbGpq1C", "cluster_name": "elasticsearch", "cluster_uuid": "5Tk8gpHfRKqQPT6A3BWG-Q", "version": { "number": "5.6.11", "build_hash": "bc3eef4", "build_date": "2018-08-16T15:25:17.293Z", "build_snapshot": false, "lucene_version": "6.6.1" }, "tagline": "You Know, for Search" }
二、SpringBoot与Elasticsearch整合使用
SpringBoot默认支持两种技术与Elasticsearch交互:
- Jest
- Spring Data Elasticsearch(默认生效)
1. Srping Boot使用Jest操作Elasticsearch
jest托管在git上,可以在git上查看文档,jest文档
1)、在application.properties中配置Elasticsearch
spring.elasticsearch.jest.uris=http://192.168.0.114:9200
2)、在pom.xml中导入依赖,由于我的elasticsearch是5.6.11版本,所以我使用的jest的版本也是5.x.x版本
<!-- 导入jest依赖 --> <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>5.3.4</version> </dependency>
3)、创建实体类
package com.example.elasticsearch.entity; import io.searchbox.annotations.JestId; import java.util.Date; public class ArticleEntity { /** 标注主键 **/ @JestId private Integer id; private String title; private String author; private Date createTime; private String content; public ArticleEntity() { } public ArticleEntity(Integer id, String title, String author, Date createTime, String content) { this.id = id; this.title = title; this.author = author; this.createTime = createTime; this.content = content; } // 省略get、set、toString }
4)、测试
@RunWith(SpringRunner.class) @SpringBootTest public class SpringBootElasticsearchApplicationTests { @Autowired private JestClient jestClient; private final static Logger log = LoggerFactory.getLogger(SpringBootElasticsearchApplicationTests.class); /** * 将数据存储在elasticsearch中 */ @Test public void test01() { ArticleEntity articleEntity = new ArticleEntity(1, "好消息", "张三", new Date(), "这是一个好消息"); /** * 创建一个完整的索引(包括索引、类型和文档) * Builder中的参数是要存储到elasticsearch中的数据(文档) * index中的参数是索引值 * type中的参数是类型值 */ Index index = new Index.Builder(articleEntity).index("news").type("article").build(); try { // 执行 jestClient.execute(index); } catch (IOException e) { e.printStackTrace(); } } /** * 从elasticsearch中检索数据 */ @Test public void test02() { // 查询语句:查询content中包含"消息"短语的所有文档 String query = "{\n" + " \"query\" : {\n" + " \"match_phrase\" : {\n" + " \"content\" : \"消息\"\n" + " }\n" + " }\n" + "}"; // 构建搜索 Search search = new Search.Builder(query).addIndex("news").addType("article").build(); try { // 执行 SearchResult result = jestClient.execute(search); List<SearchResult.Hit<ArticleEntity, Void>> list = result.getHits(ArticleEntity.class); if(list.size() > 0) { for(SearchResult.Hit<ArticleEntity, Void> hit : list) { log.info("{}", hit.source); } } } catch (IOException e) { e.printStackTrace(); } } }
2、Spring Boot使用Spring data elasticsearch操作Elasticsearch
特别要注意一下Spring data elasticsearch与Elasticsearch版本的适配
spring data elasticsearch elasticsearch 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 由于前面使用的Elasticsearch版本是5.6.11,而项目中使用的Spring data elasticsearch版本是2.1.14,所以需要调整Spring data elasticsearch版本或elasticsearch版本,我们选择调整elasticsearch版本为2.4.0
1)、docker操作
停止5.6.11版本的elasticsearch容器
# ES01是创建elasticsearch容器时取的名字,也可以是镜像id [root@localhost ~]# docker stop ES01
拉取镜像
[root@localhost ~]# docker pull elasticsearch:2.4.0
创建并运行elasticsearch容器
[root@localhost ~]# docker run -d -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -p 9200:9200 -p 9300:9300 --name ES02 35c9803ff4f4
在浏览器中输入地址http://192.168.0.114:9200/访问
// 20180902213323 // http://192.168.0.114:9200/ { "name": "Sharon Carter", "cluster_name": "elasticsearch", "version": { "number": "2.4.0", "build_hash": "ce9f0c7394dee074091dd1bc4e9469251181fc55", "build_timestamp": "2016-08-29T09:14:17Z", "build_snapshot": false, "lucene_version": "5.5.2" }, "tagline": "You Know, for Search" }
可以看到,elasticsearch版本变成了2.4.0
1)、在application.properties中配置Elasticsearch
# 和上面在浏览器中访问http://192.168.0.114:9200时返回的josn串中的cluster_name一致 spring.data.elasticsearch.cluster-name=elasticsearch # 端口是9300,而不是9200 spring.data.elasticsearch.cluster-nodes=192.168.0.114:9300
2)、在pom.xml中导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
3)、创建实体类
package com.example.elasticsearch.entity; import org.springframework.data.elasticsearch.annotations.Document; // 指定索引和类型 @Document(indexName = "library", type = "book") public class BookEntity { private Integer id; private String bookName; private String author; private Double price; public BookEntity() { } public BookEntity(Integer id, String bookName, String author, Double price) { this.id = id; this.bookName = bookName; this.author = author; this.price = price; } // 省略get、set、toString方法 }
4)、Spring data elasticsearch操作elasticsearch
官方文档:https://docs.spring.io/spring-data/elasticsearch/docs/3.1.0.RC2/reference/html/
使用ElasticsearchRepository操作elasticsearch
ElasticsearchRepository的用法与JpaRepository操作数据库差不多
创建BookElasticsearchRepository接口继承ElasticsearchRepository
public interface BookElasticsearchRepository extends ElasticsearchRepository<BookEntity, Integer> { // 根据命名规则写方法名,自动生成查询语句 List<BookEntity> findAllByBookNameLike(String bookName); // 自己写查询语句 @Query("{\n" + " \"query\" : {\n" + " \"match\" : {\n" + " \"bookName\" : \"梦\"\n" + " }\n" + " }\n" + "}") List<BookEntity> findAllBook(); }
测试
@RunWith(SpringRunner.class) @SpringBootTest public class SpringBootElasticsearchDataTests { @Autowired private BookElasticsearchRepository bookElasticsearchRepository; private final static Logger log = LoggerFactory.getLogger(SpringBootElasticsearchDataTests.class); /** * 向elasticsearch中添加数据 */ @Test public void test01() { BookEntity bookEntity = new BookEntity(1, "红楼梦", "曹雪芹", 58.0); bookElasticsearchRepository.index(bookEntity); } /*** * 使用ElasticsearchRepository自带的方法 */ @Test public void test02() { BookEntity bookEntity = bookElasticsearchRepository.findOne(1); log.info("{}", bookEntity); } /** * 使用自定义方法名的方法 */ @Test public void test03() { List<BookEntity> books = bookElasticsearchRepository.findAllByBookNameLike("梦"); if(books.size() > 0) { for(BookEntity book : books) { log.info("{}", book); } } } /** * 使用带查询语句的方法 */ @Test public void test04() { List<BookEntity> books = bookElasticsearchRepository.findAllBook(); if(books.size() > 0) { for(BookEntity book : books) { log.info("{}", book); } } } }
使用ElasticsearchTemplate 操作elasticsearch
@RunWith(SpringRunner.class) @SpringBootTest public class SpringBootElasticsearchDataTemplateTests { @Autowired private ElasticsearchTemplate elasticsearchTemplate; private final static Logger log = LoggerFactory.getLogger(SpringBootElasticsearchDataTemplateTests.class); @Test public void test01() { SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .build(); Page<BookEntity> bookEntitiePage = elasticsearchTemplate.queryForPage(searchQuery,BookEntity.class); if(bookEntitiePage.getContent().size() > 0) { for(BookEntity bookEntity : bookEntitiePage.getContent()) { log.info("{}", bookEntity); } } } }