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 版本对比:
1.3、搭建Spring Data Elasticsearch框架项目
首先创建一个简单的 java se Maven 项目,然后修改pom文件,增加依赖,如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compiler.source>1.7</maven.compiler.source>
- <maven.compiler.target>1.7</maven.compiler.target>
- </properties>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.3.6.RELEASE</version>
- <relativePath/>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-devtools</artifactId>
- <scope>runtime</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-test</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- </dependency>
- </dependencies>
- </project>
在 resources 目录中增加application.properties文件,内容如下:
- # es 服务地址
- elasticsearch.host=127.0.0.1
- # es 服务端口
- elasticsearch.port=9200
- # 配置日志级别,开启 debug 日志
- logging.level.com.atguigu.es=debug
Spring Boot 主程序:
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- @SpringBootApplication
- public class MainApplication {
- public static void main(String[] args) {
- SpringApplication.run(MainApplication.class, args);
- }
- }
数据实体类:
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import lombok.ToString;
- import org.springframework.data.annotation.Id;
- import org.springframework.data.elasticsearch.annotations.Document;
- import org.springframework.data.elasticsearch.annotations.Field;
- import org.springframework.data.elasticsearch.annotations.FieldType;
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @ToString
- @Document(indexName = "shopping", shards = 3, replicas = 1)
- public class Product {
- //必须有 id,这里的 id 是全局唯一的标识,等同于 es 中的"_id"
- @Id
- private Long id;//商品唯一标识
- /**
- * type : 字段数据类型
- * analyzer : 分词器类型
- * index : 是否索引(默认:true)
- * Keyword : 短语,不进行分词
- */
- @Field(type = FieldType.Text, analyzer = "ik_max_word")
- private String title;//商品名称
- @Field(type = FieldType.Keyword)
- private String category;//分类名称
- @Field(type = FieldType.Double)
- private Double price;//商品价格
- @Field(type = FieldType.Keyword, index = false)
- private String images;//图片地址
- }
配置类
- ElasticsearchRestTemplate是spring-data-elasticsearch项目中的一个类,和其他spring项目中的 template 类似。
- 在新版的spring-data-elasticsearch 中,ElasticsearchRestTemplate 代替了原来的ElasticsearchTemplate。
- 原因是ElasticsearchTemplate基于TransportClient,TransportClient即将在8.x 以后的版本中移除。所以,我们推荐使用ElasticsearchRestTemplate。
- ElasticsearchRestTemplate基于RestHighLevelClient客户端的。需要自定义配置类,继承AbstractElasticsearchConfiguration,并实现elasticsearchClient()抽象方法,创建RestHighLevelClient对象。
AbstractElasticsearchConfiguration源码:
- package org.example;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.springframework.context.annotation.Bean;
- import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
- import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
- import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
- import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
- public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport {
- //需重写本方法
- public abstract RestHighLevelClient elasticsearchClient();
- @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
- public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
- return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter);
- }
- }
需要自定义配置类,继承AbstractElasticsearchConfiguration,并实现elasticsearchClient()抽象方法,创建RestHighLevelClient对象,如下:
- import lombok.Data;
- import org.apache.http.HttpHost;
- import org.elasticsearch.client.RestClient;
- import org.elasticsearch.client.RestClientBuilder;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
- @ConfigurationProperties(prefix = "elasticsearch")
- @Configuration
- @Data
- public class ElasticsearchConfig extends AbstractElasticsearchConfiguration{
- private String host ;
- private Integer port ;
- //重写父类方法
- @Override
- public RestHighLevelClient elasticsearchClient() {
- RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
- RestHighLevelClient restHighLevelClient = new
- RestHighLevelClient(builder);
- return restHighLevelClient;
- }
- }
DAO 数据访问对象
- import com.lun.model.Product;
- import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
- import org.springframework.stereotype.Repository;
- @Repository
- public interface ProductDao extends ElasticsearchRepository<Product, Long>{
- }
1.4、索引操作
- import com.lun.model.Product;
- 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.data.elasticsearch.core.ElasticsearchRestTemplate;
- import org.springframework.test.context.junit4.SpringRunner;
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class SpringDataESIndexTest {
- //注入 ElasticsearchRestTemplate
- @Autowired
- private ElasticsearchRestTemplate elasticsearchRestTemplate;
- //创建索引并增加映射配置
- @Test
- public void createIndex(){
- //创建索引,系统初始化会自动创建索引
- System.out.println("创建索引");
- }
- @Test
- public void deleteIndex(){
- //创建索引,系统初始化会自动创建索引
- boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);
- System.out.println("删除索引 = " + flg);
- }
- }
执行之后可以看到数据实体类 Product 中指定的索引会被自动创建或删除。
1.5、文档操作
- 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.data.domain.Page;
- import org.springframework.data.domain.PageRequest;
- import org.springframework.data.domain.Sort;
- import org.springframework.test.context.junit4.SpringRunner;
- import java.util.ArrayList;
- import java.util.List;
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class SpringDataESProductDaoTest {
- @Autowired
- private ProductDao productDao;
- /**
- * 新增
- */
- @Test
- public void save(){
- Product product = new Product();
- product.setId(2L);
- product.setTitle("华为手机");
- product.setCategory("手机");
- product.setPrice(2999.0);
- product.setImages("http://www.atguigu/hw.jpg");
- productDao.save(product);
- }
- //POSTMAN, GET http://localhost:9200/product/_doc/2
- //修改
- @Test
- public void update(){
- Product product = new Product();
- product.setId(2L);
- product.setTitle("小米 2 手机");
- product.setCategory("手机");
- product.setPrice(9999.0);
- product.setImages("http://www.atguigu/xm.jpg");
- productDao.save(product);
- }
- //POSTMAN, GET http://localhost:9200/product/_doc/2
- //根据 id 查询
- @Test
- public void findById(){
- Product product = productDao.findById(2L).get();
- System.out.println(product);
- }
- @Test
- public void findAll(){
- Iterable<Product> products = productDao.findAll();
- for (Product product : products) {
- System.out.println(product);
- }
- }
- //删除
- @Test
- public void delete(){
- Product product = new Product();
- product.setId(2L);
- productDao.delete(product);
- }
- //POSTMAN, GET http://localhost:9200/product/_doc/2
- //批量新增
- @Test
- public void saveAll(){
- List<Product> productList = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- Product product = new Product();
- product.setId(Long.valueOf(i));
- product.setTitle("["+i+"]小米手机");
- product.setCategory("手机");
- product.setPrice(1999.0 + i);
- product.setImages("http://www.atguigu/xm.jpg");
- productList.add(product);
- }
- productDao.saveAll(productList);
- }
- //分页查询
- @Test
- public void findByPageable(){
- //设置排序(排序方式,正序还是倒序,排序的 id)
- Sort sort = Sort.by(Sort.Direction.DESC,"id");
- int currentPage=0;//当前页,第一页从 0 开始, 1 表示第二页
- int pageSize = 5;//每页显示多少条
- //设置查询分页
- PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
- //分页查询
- Page<Product> productPage = productDao.findAll(pageRequest);
- for (Product Product : productPage.getContent()) {
- System.out.println(Product);
- }
- }
- }
上面执行完后结果分别如下:
1)新增 2)修改 3)根据 id 查询文档
4)查询所有文档 5)批量新增
6)分页查询
1.6、文档搜索
- import org.elasticsearch.index.query.MatchQueryBuilder;
- import org.elasticsearch.index.query.QueryBuilders;
- import org.elasticsearch.index.query.TermQueryBuilder;
- 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.data.domain.PageRequest;
- import org.springframework.test.context.junit4.SpringRunner;
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class SpringDataESSearchTest {
- @Autowired
- private ProductDao productDao;
- /**
- * term 查询
- * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
- */
- @Test
- public void termQuery(){
- MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("title", "华为手机");
- Iterable<Product> products = productDao.search(termQueryBuilder);
- for (Product product : products) {
- System.out.println(product);
- }
- }
- /**
- * term 查询加分页
- */
- @Test
- public void termQueryByPage(){
- int currentPage= 0 ;
- int pageSize = 5;
- //设置查询分页
- PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
- MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("title", "华为手机");
- Iterable<Product> products =
- productDao.search(termQueryBuilder,pageRequest);
- for (Product product : products) {
- System.out.println(product);
- }
- }
- }
上面执行完后结果分别如下:
- match查询:
- 分页查询:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?