本文共 7299 字,大约阅读时间需要 24 分钟。
本文将详细介绍如何在 Spring Boot 项目中集成 Elasticsearch,并通过实际代码示例展示两种主要的操作方式:Spring Data Elasticsearch Repositories 和 Elasticsearch Template。
在开始操作之前,需要确保以下几点:
elasticsearch.yml 文件,配置如下:cluster.name: my-applicationnetwork.host: 192.168.1.134http.port: 9200
此外,建议对以下文件进行调整:
/etc/security/limits.conf
cheng soft nofile 65536cheng hard nofile 65536
/etc/sysctl.conf
vm.max_map_count=262144
Spring Boot 2.0.5 默认的 Elasticsearch 版本较低,本文将使用最新版本 6.4.1。同时,确保 spring-data-elasticsearch 的版本升级到 3.1.0,以避免类似 NoClassDefFoundError 的问题。
在项目的 pom.xml 中,添加以下依赖项:
org.elasticsearch elasticsearch ${elasticsearch.version} org.elasticsearch.client transport ${elasticsearch.version} org.elasticsearch.client elasticsearch-rest-client ${elasticsearch.version} org.elasticsearch.plugin transport-netty4-client ${elasticsearch.version} org.springframework.data spring-data-elasticsearch ${spring.data.elasticsearch.version} org.springframework.boot spring-boot-starter-data-elasticsearch
在 application.properties 中添加以下配置:
spring.data.elasticsearch.cluster-name=my-applicationspring.data.elasticsearch.cluster-nodes=192.168.1.134:9300
注意事项:配置文件中 9200 是通过 HTTP 端口定义的,而 9300 是通过 TCP 端口定义的,两者均为 Elasticsearch 的常用端口。
定义一个用于存储商品信息的实体类:
@Data@Document(indexName = "commodity")public class Commodity implements Serializable { @Id private String skuId; private String name; private String category; private Integer price; private String brand; private Integer stock;} 创建一个 DAO 接口,继承 ElasticsearchRepository:
@Repositorypublic interface CommodityRepository extends ElasticsearchRepository {} 定义一个服务接口,包含 CRUD 和查询操作:
public interface CommodityService { long count(); Commodity save(Commodity commodity); void delete(Commodity commodity); Iterable getAll(); List getByName(String name); Page pageQuery(Integer pageNo, Integer pageSize, String kw);} 实现上述接口的具体类:
@Servicepublic class CommodityServiceImpl implements CommodityService { @Autowired private CommodityRepository commodityRepository; @Override public long count() { return commodityRepository.count(); } @Override public Commodity save(Commodity commodity) { return commodityRepository.save(commodity); } @Override public void delete(Commodity commodity) { commodityRepository.delete(commodity); commodityRepository.deleteById(commodity.getSkuId()); } @Override public Iterable getAll() { return commodityRepository.findAll(); } @Override public List getByName(String name) { List list = new ArrayList<>(); MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("name", name); Iterable iterable = commodityRepository.search(matchQueryBuilder); iterable.forEach(e -> list.add(e)); return list; } @Override public Page pageQuery(Integer pageNo, Integer pageSize, String kw) { SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchPhraseQuery("name", kw)) .withPageable(PageRequest.of(pageNo, pageSize)) .build(); return commodityRepository.search(searchQuery); }} 创建测试类,验证各项功能:
@RunWith(SpringRunner.class)@SpringBootTestpublic class CjsElasticsearchExampleApplicationTests { @Autowired private CommodityService commodityService; @Test public void contextLoads() { System.out.println(commodityService.count()); } @Test public void testInsert() { Commodity commodity = new Commodity(); commodity.setSkuId("1501009001"); commodity.setName("原味切片面包(10片装)"); commodity.setCategory("101"); commodity.setPrice(880); commodity.setBrand("良品铺子"); commodityService.save(commodity); commodity = new Commodity(); commodity.setSkuId("1501009002"); commodity.setName("原味切片面包(6片装)"); commodity.setCategory("101"); commodity.setPrice(680); commodity.setBrand("良品铺子"); commodityService.save(commodity); commodity = new Commodity(); commodity.setSkuId("1501009004"); commodity.setName("元气吐司850g"); commodity.setCategory("101"); commodity.setPrice(120); commodity.setBrand("百草味"); commodityService.save(commodity); } @Test public void testDelete() { Commodity commodity = new Commodity(); commodity.setSkuId("1501009002"); commodityService.delete(commodity); } @Test public void testGetAll() { Iterable iterable = commodityService.getAll(); iterable.forEach(e -> System.out.println(e.toString())); } @Test public void testGetByName() { List list = commodityService.getByName("面包"); System.out.println(list); } @Test public void testPage() { Page page = commodityService.pageQuery(0, 10, "切片"); System.out.println(page.getTotalPages()); System.out.println(page.getNumber()); System.out.println(page.getContent()); }} 创建一个测试类,使用 Elasticsearch Template 进行操作:
@RunWith(SpringRunner.class)@SpringBootTestpublic class ElasticsearchTemplateTest { @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Test public void testInsert() { Commodity commodity = new Commodity(); commodity.setSkuId("1501009005"); commodity.setName("葡萄吐司面包(10片装)"); commodity.setCategory("101"); commodity.setPrice(160); commodity.setBrand("良品铺子"); IndexQuery indexQuery = new IndexQueryBuilder().withObject(commodity).build(); elasticsearchTemplate.index(indexQuery); } @Test public void testQuery() { SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("name", "吐司")) .build(); List list = elasticsearchTemplate.queryForList(searchQuery, Commodity.class); System.out.println(list); }} src/├── main/│ ├── java/│ │ ├── com/│ │ │ └── cjs/│ │ │ ├── example/│ │ │ │ ├── entity/│ │ │ │ └── dao/│ │ │ └── service/│ │ └── impl/│ └── resources/│ └── application.properties