Java框架集成ES

 


1、SpringData Elasticsearch框架集成

1.1、SpringData 框架基本介绍

Spring Data是一个用于简化数据库、非关系型数据库、索引库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持 map-reduce框架和云计算数据服务。Spring Data可以极大的简化JPA(Elasticsearch…)的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD 外,还包括如分页、排序等一些常用的功能。

Spring Data 的官网:https://spring.io/projects/spring-data

Spring Data 常用的功能模块如下:

 

1.2、Spring Data Elasticsearch 框架基本介绍

Spring Data Elasticsearch 基于 spring data API 简化 Elasticsearch 操作,将原始操作Elasticsearch 的客户端 API 进行封装 。Spring Data 为 Elasticsearch 项目提供集成搜索引擎。Spring Data Elasticsearch POJO 的关键功能区域为中心的模型与 Elastichsearch 交互文档和轻松地编写一个存储索引库数据访问层。官方网站: https://spring.io/projects/spring-data-elasticsearch 

Spring Data Elasticsearch 版本对比:

目前最新 springboot 对应 Elasticsearch7.6.2,Spring boot2.3.x 一般可以兼容 Elasticsearch7.x。

 

1.3、搭建Spring Data Elasticsearch框架项目

首先创建一个简单的 java se Maven 项目,然后修改pom文件,增加依赖,如下:

复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <project xmlns="http://maven.apache.org/POM/4.0.0" 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. <properties>
  8. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  9. <maven.compiler.source>1.7</maven.compiler.source>
  10. <maven.compiler.target>1.7</maven.compiler.target>
  11. </properties>
  12.  
  13. <parent>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-parent</artifactId>
  16. <version>2.3.6.RELEASE</version>
  17. <relativePath/>
  18. </parent>
  19.  
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.projectlombok</groupId>
  23. <artifactId>lombok</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-devtools</artifactId>
  32. <scope>runtime</scope>
  33. <optional>true</optional>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-test</artifactId>
  38. <scope>test</scope>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-test</artifactId>
  43. </dependency>
  44. <dependency>
  45. <groupId>junit</groupId>
  46. <artifactId>junit</artifactId>
  47. </dependency>
  48. <dependency>
  49. <groupId>org.springframework</groupId>
  50. <artifactId>spring-test</artifactId>
  51. </dependency>
  52. </dependencies>
  53. </project>
复制代码

在 resources 目录中增加application.properties文件,内容如下:

复制代码
  1. # es 服务地址
  2. elasticsearch.host=127.0.0.1
  3. # es 服务端口
  4. elasticsearch.port=9200
  5. # 配置日志级别,开启 debug 日志
  6. logging.level.com.atguigu.es=debug
复制代码

Spring Boot 主程序:

复制代码
  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. @SpringBootApplication
  4. public class MainApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(MainApplication.class, args);
  7. }
  8. }
复制代码

数据实体类:

复制代码
  1. import lombok.AllArgsConstructor;
  2. import lombok.Data;
  3. import lombok.NoArgsConstructor;
  4. import lombok.ToString;
  5. import org.springframework.data.annotation.Id;
  6. import org.springframework.data.elasticsearch.annotations.Document;
  7. import org.springframework.data.elasticsearch.annotations.Field;
  8. import org.springframework.data.elasticsearch.annotations.FieldType;
  9. @Data
  10. @NoArgsConstructor
  11. @AllArgsConstructor
  12. @ToString
  13. @Document(indexName = "shopping", shards = 3, replicas = 1)
  14. public class Product {
  15. //必须有 id,这里的 id 是全局唯一的标识,等同于 es 中的"_id"
  16. @Id
  17. private Long id;//商品唯一标识
  18.  
  19. /**
  20. * type : 字段数据类型
  21. * analyzer : 分词器类型
  22. * index : 是否索引(默认:true)
  23. * Keyword : 短语,不进行分词
  24. */
  25. @Field(type = FieldType.Text, analyzer = "ik_max_word")
  26. private String title;//商品名称
  27. @Field(type = FieldType.Keyword)
  28. private String category;//分类名称
  29. @Field(type = FieldType.Double)
  30. private Double price;//商品价格
  31. @Field(type = FieldType.Keyword, index = false)
  32. private String images;//图片地址
  33. }
复制代码

配置类

  • ElasticsearchRestTemplate是spring-data-elasticsearch项目中的一个类,和其他spring项目中的 template 类似。
  • 在新版的spring-data-elasticsearch 中,ElasticsearchRestTemplate 代替了原来的ElasticsearchTemplate。
  • 原因是ElasticsearchTemplate基于TransportClient,TransportClient即将在8.x 以后的版本中移除。所以,我们推荐使用ElasticsearchRestTemplate。
  • ElasticsearchRestTemplate基于RestHighLevelClient客户端的。需要自定义配置类,继承AbstractElasticsearchConfiguration,并实现elasticsearchClient()抽象方法,创建RestHighLevelClient对象。

AbstractElasticsearchConfiguration源码:

复制代码
  1. package org.example;
  2. import org.elasticsearch.client.RestHighLevelClient;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
  5. import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
  6. import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
  7. import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
  8.  
  9. public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport {
  10. //需重写本方法
  11. public abstract RestHighLevelClient elasticsearchClient();
  12. @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
  13. public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
  14. return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter);
  15. }
  16. }
复制代码

需要自定义配置类,继承AbstractElasticsearchConfiguration,并实现elasticsearchClient()抽象方法,创建RestHighLevelClient对象,如下:

复制代码
  1. import lombok.Data;
  2. import org.apache.http.HttpHost;
  3. import org.elasticsearch.client.RestClient;
  4. import org.elasticsearch.client.RestClientBuilder;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.springframework.boot.context.properties.ConfigurationProperties;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
  9. @ConfigurationProperties(prefix = "elasticsearch")
  10. @Configuration
  11. @Data
  12. public class ElasticsearchConfig extends AbstractElasticsearchConfiguration{
  13. private String host ;
  14. private Integer port ;
  15. //重写父类方法
  16. @Override
  17. public RestHighLevelClient elasticsearchClient() {
  18. RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
  19. RestHighLevelClient restHighLevelClient = new
  20. RestHighLevelClient(builder);
  21. return restHighLevelClient;
  22. }
  23. }
复制代码

DAO 数据访问对象

复制代码
  1. import com.lun.model.Product;
  2. import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
  3. import org.springframework.stereotype.Repository;
  4. @Repository
  5. public interface ProductDao extends ElasticsearchRepository<Product, Long>{
  6. }
复制代码

 

1.4、索引操作

复制代码
  1. import com.lun.model.Product;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. @RunWith(SpringRunner.class)
  9. @SpringBootTest
  10. public class SpringDataESIndexTest {
  11. //注入 ElasticsearchRestTemplate
  12. @Autowired
  13. private ElasticsearchRestTemplate elasticsearchRestTemplate;
  14. //创建索引并增加映射配置
  15. @Test
  16. public void createIndex(){
  17. //创建索引,系统初始化会自动创建索引
  18. System.out.println("创建索引");
  19. }
  20. @Test
  21. public void deleteIndex(){
  22. //创建索引,系统初始化会自动创建索引
  23. boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);
  24. System.out.println("删除索引 = " + flg);
  25. }
  26. }
复制代码

执行之后可以看到数据实体类 Product 中指定的索引会被自动创建或删除。

 

1.5、文档操作

复制代码
  1. import org.junit.Test;
  2. import org.junit.runner.RunWith;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import org.springframework.data.domain.Page;
  6. import org.springframework.data.domain.PageRequest;
  7. import org.springframework.data.domain.Sort;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. @RunWith(SpringRunner.class)
  12. @SpringBootTest
  13. public class SpringDataESProductDaoTest {
  14. @Autowired
  15. private ProductDao productDao;
  16. /**
  17. * 新增
  18. */
  19. @Test
  20. public void save(){
  21. Product product = new Product();
  22. product.setId(2L);
  23. product.setTitle("华为手机");
  24. product.setCategory("手机");
  25. product.setPrice(2999.0);
  26. product.setImages("http://www.atguigu/hw.jpg");
  27. productDao.save(product);
  28. }
  29. //POSTMAN, GET http://localhost:9200/product/_doc/2
  30. //修改
  31. @Test
  32. public void update(){
  33. Product product = new Product();
  34. product.setId(2L);
  35. product.setTitle("小米 2 手机");
  36. product.setCategory("手机");
  37. product.setPrice(9999.0);
  38. product.setImages("http://www.atguigu/xm.jpg");
  39. productDao.save(product);
  40. }
  41. //POSTMAN, GET http://localhost:9200/product/_doc/2
  42. //根据 id 查询
  43. @Test
  44. public void findById(){
  45. Product product = productDao.findById(2L).get();
  46. System.out.println(product);
  47. }
  48. @Test
  49. public void findAll(){
  50. Iterable<Product> products = productDao.findAll();
  51. for (Product product : products) {
  52. System.out.println(product);
  53. }
  54. }
  55. //删除
  56. @Test
  57. public void delete(){
  58. Product product = new Product();
  59. product.setId(2L);
  60. productDao.delete(product);
  61. }
  62. //POSTMAN, GET http://localhost:9200/product/_doc/2
  63. //批量新增
  64. @Test
  65. public void saveAll(){
  66. List<Product> productList = new ArrayList<>();
  67. for (int i = 0; i < 10; i++) {
  68. Product product = new Product();
  69. product.setId(Long.valueOf(i));
  70. product.setTitle("["+i+"]小米手机");
  71. product.setCategory("手机");
  72. product.setPrice(1999.0 + i);
  73. product.setImages("http://www.atguigu/xm.jpg");
  74. productList.add(product);
  75. }
  76. productDao.saveAll(productList);
  77. }
  78. //分页查询
  79. @Test
  80. public void findByPageable(){
  81. //设置排序(排序方式,正序还是倒序,排序的 id)
  82. Sort sort = Sort.by(Sort.Direction.DESC,"id");
  83. int currentPage=0;//当前页,第一页从 0 开始, 1 表示第二页
  84. int pageSize = 5;//每页显示多少条
  85. //设置查询分页
  86. PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
  87. //分页查询
  88. Page<Product> productPage = productDao.findAll(pageRequest);
  89. for (Product Product : productPage.getContent()) {
  90. System.out.println(Product);
  91. }
  92. }
  93. }
复制代码

上面执行完后结果分别如下:

1)新增  2)修改  3)根据 id 查询文档

  

4)查询所有文档  5)批量新增

6)分页查询

 

1.6、文档搜索

复制代码
  1. import org.elasticsearch.index.query.MatchQueryBuilder;
  2. import org.elasticsearch.index.query.QueryBuilders;
  3. import org.elasticsearch.index.query.TermQueryBuilder;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.data.domain.PageRequest;
  9. import org.springframework.test.context.junit4.SpringRunner;
  10. @RunWith(SpringRunner.class)
  11. @SpringBootTest
  12. public class SpringDataESSearchTest {
  13. @Autowired
  14. private ProductDao productDao;
  15. /**
  16. * term 查询
  17. * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
  18. */
  19. @Test
  20. public void termQuery(){
  21. MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("title", "华为手机");
  22. Iterable<Product> products = productDao.search(termQueryBuilder);
  23. for (Product product : products) {
  24. System.out.println(product);
  25. }
  26. }
  27. /**
  28. * term 查询加分页
  29. */
  30. @Test
  31. public void termQueryByPage(){
  32. int currentPage= 0 ;
  33. int pageSize = 5;
  34. //设置查询分页
  35. PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
  36. MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("title", "华为手机");
  37. Iterable<Product> products =
  38. productDao.search(termQueryBuilder,pageRequest);
  39. for (Product product : products) {
  40. System.out.println(product);
  41. }
  42. }
  43. }
复制代码

上面执行完后结果分别如下:

  • match查询:

  • 分页查询:

 

posted @   wenxuehai  阅读(489)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
//右下角添加目录
点击右上角即可分享
微信分享提示