作者:废物大师兄 cnblogs.com/cjsblog/p/9756978.html
1. 前言
1.1. 集成方式
Spring Boot中集成Elasticsearch有4种方式:
-
REST Client
-
Jest
-
Spring Data
-
Spring Data Elasticsearch Repositories
本文用后面两种方式来分别连接并操作Elasticsearch
1.2. 环境与配置
服务端:elasticsearch-6.3.2 1台
客户端:elasticsearch 6.4.1
服务端配置文件:elasticsearch.yml
1cluster.name: my-application 2network.host: 192.168.1.134 3http.port: 9200
/etc/security/limits.conf
1cheng soft nofile 65536 2cheng hard nofile 65536
/etc/sysctl.conf
vm.max\_map\_count=262144
1.3. 版本
Spring Boot 2.0.5默认的elasticsearch版本很低,这里我们用最新版本6.4.1
如果启动过程中出现
java.lang.NoClassDefFoundError: org/elasticsearch/common/transport/InetSocketTransportAddress
则说明,elasticsearch依赖的jar包版本不一致,统一改成6.4.1即可
另外,Spring Boot 2.0.5依赖的spring-data-elasticsearch版本是3.0.1,需要升级到3.1.0

2. 依赖
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>com.cjs.example</groupId> 7 <artifactId>cjs-elasticsearch-example</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>cjs-elasticsearch-example</name> 12 <description></description> 13 14 <parent> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-parent</artifactId> 17 <version>2.0.5.RELEASE</version> 18 <relativePath/> <!-- lookup parent from repository --> 19 </parent> 20 21 <properties> 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 23 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 24 <java.version>1.8</java.version> 25 26 <elasticsearch.version>6.4.1</elasticsearch.version> 27 <spring.data.elasticsearch.version>3.1.0.RELEASE</spring.data.elasticsearch.version> 28 </properties> 29 30 <dependencies> 31 <dependency> 32 <groupId>org.elasticsearch</groupId> 33 <artifactId>elasticsearch</artifactId> 34 <version>${elasticsearch.version}</version> 35 </dependency> 36 <dependency> 37 <groupId>org.elasticsearch.client</groupId> 38 <artifactId>transport</artifactId> 39 <version>${elasticsearch.version}</version> 40 </dependency> 41 <dependency> 42 <groupId>org.elasticsearch.client</groupId> 43 <artifactId>elasticsearch-rest-client</artifactId> 44 <version>${elasticsearch.version}</version> 45 </dependency> 46 <dependency> 47 <groupId>org.elasticsearch.plugin</groupId> 48 <artifactId>transport-netty4-client</artifactId> 49 <version>${elasticsearch.version}</version> 50 </dependency> 51 <dependency> 52 <groupId>org.springframework.data</groupId> 53 <artifactId>spring-data-elasticsearch</artifactId> 54 <version>${spring.data.elasticsearch.version}</version> 55 </dependency> 56 <dependency> 57 <groupId>org.springframework.boot</groupId> 58 <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 59 </dependency> 60 <dependency> 61 <groupId>org.springframework.boot</groupId> 62 <artifactId>spring-boot-starter-web</artifactId> 63 </dependency> 64 65 <dependency> 66 <groupId>org.projectlombok</groupId> 67 <artifactId>lombok</artifactId> 68 <optional>true</optional> 69 </dependency> 70 <dependency> 71 <groupId>org.springframework.boot</groupId> 72 <artifactId>spring-boot-starter-test</artifactId> 73 <scope>test</scope> 74 </dependency> 75 </dependencies> 76 77 <build> 78 <plugins> 79 <plugin> 80 <groupId>org.springframework.boot</groupId> 81 <artifactId>spring-boot-maven-plugin</artifactId> 82 </plugin> 83 </plugins> 84 </build> 85 86</project>
3. application.properties
1spring.data.elasticsearch.cluster-name=my-application 2spring.data.elasticsearch.cluster-nodes=192.168.1.134:9300
也许,大家会疑惑,配置文件中明明写的端口是9200,为何这里配置文件中连接的时候写的端口是9300呢?
因为,配置9200是通过HTTP连接的端口,9300是TCP连接的端口

4. 操作
4.1. 使用Spring Data Elasticsearch Repositories操作Elasticsearch
首先,定义一个实体类
1package com.cjs.example.entity; 2 3import lombok.Data; 4import org.springframework.data.annotation.Id; 5import org.springframework.data.elasticsearch.annotations.Document; 6 7import java.io.Serializable; 8 9@Data 10@Document(indexName = "commodity") 11public class Commodity implements Serializable { 12 13 @Id 14 private String skuId; 15 16 private String name; 17 18 private String category; 19 20 private Integer price; 21 22 private String brand; 23 24 private Integer stock; 25 26}
这里定义了Commodity实例,表示商品。在Elasticsearch 6.X 版本中,不建议使用type,而且在7.X版本中将会彻底废弃type,所以此处我只指定了indexName,没有指定type。
这里,一个Commodity代表一个商品,同时代表一条索引记录。
类比关系型数据库的话,Index相当于表,Document相当于记录,然后,需要自己定义一个接口,并继承ElasticsearchRepository。

1package com.cjs.example.dao; 2 3import com.cjs.example.entity.Commodity; 4import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5import org.springframework.stereotype.Repository; 6 7@Repository 8public interface CommodityRepository extends ElasticsearchRepository<Commodity, String> { 9 10}
这里的Repository相当于DAO,操作mysql还是elasticsearch都是一样的
接下来,定义service接口
1package com.cjs.example.service; 2 3import com.cjs.example.entity.Commodity; 4import org.springframework.data.domain.Page; 5 6import java.util.List; 7 8public interface CommodityService { 9 10 long count(); 11 12 Commodity save(Commodity commodity); 13 14 void delete(Commodity commodity); 15 16 Iterable<Commodity> getAll(); 17 18 List<Commodity> getByName(String name); 19 20 Page<Commodity> pageQuery(Integer pageNo, Integer pageSize, String kw); 21 22}
实现类
1package com.cjs.example.service.impl; 2 3import com.cjs.example.entity.Commodity; 4import com.cjs.example.dao.CommodityRepository; 5import com.cjs.example.service.CommodityService; 6import org.elasticsearch.index.query.MatchQueryBuilder; 7import org.elasticsearch.index.query.QueryBuilders; 8import org.springframework.beans.factory.annotation.Autowired; 9import org.springframework.data.domain.Page; 10import org.springframework.data.domain.PageRequest; 11import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; 12import org.springframework.data.elasticsearch.core.query.SearchQuery; 13import org.springframework.stereotype.Service; 14 15import java.util.ArrayList; 16import java.util.List; 17 18@Service 19public class CommodityServiceImpl implements CommodityService { 20 21 @Autowired 22 private CommodityRepository commodityRepository; 23 24 @Override 25 public long count() { 26 return commodityRepository.count(); 27 } 28 29 @Override 30 public Commodity save(Commodity commodity) { 31 return commodityRepository.save(commodity); 32 } 33 34 @Override 35 public void delete(Commodity commodity) { 36 commodityRepository.delete(commodity); 37// commodityRepository.deleteById(commodity.getSkuId()); 38 } 39 40 @Override 41 public Iterable<Commodity> getAll() { 42 return commodityRepository.findAll(); 43 } 44 45 @Override 46 public List<Commodity> getByName(String name) { 47 List<Commodity> list = new ArrayList<>(); 48 MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("name", name); 49 Iterable<Commodity> iterable = commodityRepository.search(matchQueryBuilder); 50 iterable.forEach(e->list.add(e)); 51 return list; 52 } 53 54 @Override 55 public Page<Commodity> pageQuery(Integer pageNo, Integer pageSize, String kw) { 56 SearchQuery searchQuery = new NativeSearchQueryBuilder() 57 .withQuery(QueryBuilders.matchPhraseQuery("name", kw)) 58 .withPageable(PageRequest.of(pageNo, pageSize)) 59 .build(); 60 return commodityRepository.search(searchQuery); 61 } 62 63}
在这个Service中演示了增删查改操作,还有分页查询
最后,写一个测试类测试其中的方法
1package com.cjs.example; 2 3import com.cjs.example.entity.Commodity; 4import com.cjs.example.service.CommodityService; 5import org.junit.Test; 6import org.junit.runner.RunWith; 7import org.springframework.beans.factory.annotation.Autowired; 8import org.springframework.boot.test.context.SpringBootTest; 9import org.springframework.data.domain.Page; 10import org.springframework.test.context.junit4.SpringRunner; 11 12import java.util.List; 13 14@RunWith(SpringRunner.class) 15@SpringBootTest 16public class CjsElasticsearchExampleApplicationTests { 17 18 @Autowired 19 private CommodityService commodityService; 20 21 @Test 22 public void contextLoads() { 23 System.out.println(commodityService.count()); 24 } 25 26 @Test 27 public void testInsert() { 28 Commodity commodity = new Commodity(); 29 commodity.setSkuId("1501009001"); 30 commodity.setName("原味切片面包(10片装)"); 31 commodity.setCategory("101"); 32 commodity.setPrice(880); 33 commodity.setBrand("良品铺子"); 34 commodityService.save(commodity); 35 36 commodity = new Commodity(); 37 commodity.setSkuId("1501009002"); 38 commodity.setName("原味切片面包(6片装)"); 39 commodity.setCategory("101"); 40 commodity.setPrice(680); 41 commodity.setBrand("良品铺子"); 42 commodityService.save(commodity); 43 44 commodity = new Commodity(); 45 commodity.setSkuId("1501009004"); 46 commodity.setName("元气吐司850g"); 47 commodity.setCategory("101"); 48 commodity.setPrice(120); 49 commodity.setBrand("百草味"); 50 commodityService.save(commodity); 51 52 } 53 54 @Test 55 public void testDelete() { 56 Commodity commodity = new Commodity(); 57 commodity.setSkuId("1501009002"); 58 commodityService.delete(commodity); 59 } 60 61 @Test 62 public void testGetAll() { 63 Iterable<Commodity> iterable = commodityService.getAll(); 64 iterable.forEach(e->System.out.println(e.toString())); 65 } 66 67 @Test 68 public void testGetByName() { 69 List<Commodity> list = commodityService.getByName("面包"); 70 System.out.println(list); 71 } 72 73 @Test 74 public void testPage() { 75 Page<Commodity> page = commodityService.pageQuery(0, 10, "切片"); 76 System.out.println(page.getTotalPages()); 77 System.out.println(page.getNumber()); 78 System.out.println(page.getContent()); 79 } 80}
以上,便是使用Elasticsearch Repositories的方式
4.2. 使用ElasticsearchTemplate方式操作Elasticsearch
1package com.cjs.example; 2 3import com.cjs.example.entity.Commodity; 4import org.elasticsearch.index.query.QueryBuilders; 5import org.junit.Test; 6import org.junit.runner.RunWith; 7import org.springframework.beans.factory.annotation.Autowired; 8import org.springframework.boot.test.context.SpringBootTest; 9import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 10import org.springframework.data.elasticsearch.core.query.*; 11import org.springframework.test.context.junit4.SpringRunner; 12 13import java.util.List; 14 15@RunWith(SpringRunner.class) 16@SpringBootTest 17public class ElasticsearchTemplateTest { 18 19 @Autowired 20 public ElasticsearchTemplate elasticsearchTemplate; 21 22 @Test 23 public void testInsert() { 24 Commodity commodity = new Commodity(); 25 commodity.setSkuId("1501009005"); 26 commodity.setName("葡萄吐司面包(10片装)"); 27 commodity.setCategory("101"); 28 commodity.setPrice(160); 29 commodity.setBrand("良品铺子"); 30 31 IndexQuery indexQuery = new IndexQueryBuilder().withObject(commodity).build(); 32 elasticsearchTemplate.index(indexQuery); 33 } 34 35 @Test 36 public void testQuery() { 37 SearchQuery searchQuery = new NativeSearchQueryBuilder() 38 .withQuery(QueryBuilders.matchQuery("name", "吐司")) 39 .build(); 40 List<Commodity> list = elasticsearchTemplate.queryForList(searchQuery, Commodity.class); 41 System.out.println(list); 42 } 43 44}
ElasticsearchTemplate是自动配置的

5. 演示

6. 工程结构

7. 参考
推荐去我的博客阅读更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
觉得不错,别忘了点赞+转发哦!