springBoot项目使用Elasticsearch教程

目录

一、引言

(一)使用背景

Spring项目集成Elasticsearch可以带来许多好处,主要包括:

  • 高性能搜索:Elasticsearch是基于Lucene的分布式搜索引擎,它能提供非常高效和低延迟的全文搜索、结构化查询以及分析。对于需要快速响应的查询操作,Elasticsearch能够提供显著的性能提升。
  • 灵活的数据模型:Elasticsearch是一个文档数据库,使用JSON格式存储数据,使得数据模型非常灵活,能够处理各种结构化和半结构化数据。可以轻松应对变化的数据模型和复杂的查询需求。
  • 分布式架构:Elasticsearch的分布式架构使得它具备了强大的水平扩展能力。即使数据量增长,集群也能够通过增加节点来轻松扩展,保证性能和可用性。
  • 实时性:Elasticsearch支持近实时搜索,数据一旦写入便能立即查询。这对于报表服务、实时数据分析和监控等应用场景非常适用。
  • Spring Data Elasticsearch支持:Spring提供了Spring Data
    Elasticsearch,一个高层次的框架,用来简化Spring与Elasticsearch的集成。它封装了Elasticsearch的低层API,提供了易于使用的Repository和Template,减少了开发中的重复工作。
  • 强大的聚合功能:Elasticsearch的聚合功能非常强大,可以对大量数据进行分组、统计、计算,帮助构建各种报表和分析应用。
  • 易于集成和配置:Spring
    Boot的自动配置功能使得Elasticsearch的集成变得非常简单。你只需要在application.properties或application.yml中配置连接信息,就能快速启用Elasticsearch的功能。
  • 监控和管理工具:Elasticsearch提供了如Kibana等强大的监控和可视化工具,可以帮助开发者轻松监控和调试系统运行状态。
  • 可扩展性和适应性:随着业务需求和数据量的增长,Elasticsearch能够通过集群扩展来应对。你可以随时根据需要增加更多节点、分片等。
  • 简化的查询和索引操作:Spring Data
    Elasticsearch提供了简单易用的API来执行索引操作、查询操作、批量操作等,开发者不需要深入掌握Elasticsearch的底层操作,能专注于业务逻辑的实现。

(二)版本库区别

1.spring-boot-starter-data-elasticsearch

功能:这是Spring Boot为集成Spring Data Elasticsearch提供的启动器。它通过Spring Data提供了简化的数据访问接口,使得开发者可以更轻松地与Elasticsearch交互。

用途:适用于Spring Boot应用,尤其是当你需要一个简化的方式来存取数据,而不想处理Elasticsearch客户端的复杂配置时。它提供了ElasticsearchRepository,自动化配置,方便进行基本的CRUD操作和查询。

优点:

自动配置:Spring Boot会自动配置好Elasticsearch连接和必要的基础设置,减少了手动配置的繁琐。

面向开发者的Repository接口:通过ElasticsearchRepository接口,开发者可以像操作普通数据库一样执行Elasticsearch的基本操作(如保存、查找、删除等)。

集成其他Spring功能:能够与Spring的事务管理、数据绑定等功能紧密集成。

简化操作:隐藏了底层的客户端实现细节,适合标准的应用开发。
2. elasticsearch-rest-high-level-client 和 elasticsearch-rest-client

功能:这两个是纯粹的Elasticsearch客户端库,分别提供了较高层次(rest-high-level-client)和较低层次(rest-client)的访问接口。它们专注于与Elasticsearch服务器之间的网络通信和数据传输,不提供Spring特有的集成。

用途:这两个依赖适合需要更精细控制或更复杂的Elasticsearch操作的场景。例如,你可以在这些客户端中直接操作Elasticsearch的REST API,进行高级的索引操作、聚合查询等,甚至实现一些自定义的网络请求和数据序列化。

优点:

高灵活性:提供了更细粒度的控制,你可以直接处理请求和响应。

支持更多功能:如果你需要对Elasticsearch进行更复杂的操作,可能会发现elasticsearch-rest-high-level-client或elasticsearch-rest-client能提供更多的灵活性和控制。

  • 如果你是在SpringBoot应用中开发,且不需要过多的手动配置和细节控制,推荐使用spring-boot-starter-data-elasticsearch。
  • 使用es可以用springboot集成的es库,也可以用es提供的客户端库,本文围绕两种方式展开

二、引入依赖

两种方式均可

(一)springboot集成的es依赖(建议)

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    <version>${spring.boot.version}</version>
</dependency>

(二)es提供的客户端库

version具体以es的服务端版本为参考,需要匹配

xml 复制代码
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.10.2</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.10.2</version>
</dependency>

三、配置(以yaml文件为例)

(一)springboot集成的es依赖(建议)

yaml 复制代码
spring:
  data:
    elasticsearch:
      cluster-name: your-cluster-name
      cluster-nodes: localhost:9200  # ES节点的地址和端口
      username: 用户名
      password: 密码

(二)es提供的客户端库

yaml 复制代码
elasticsearch:
  host: 服务端主机ip
  port: 9200
  scheme: http
  username: 用户名
  password: 密码

四、代码

(一)springboot集成的es依赖(建议)

1、创建Elasticsearch实体类

你需要创建一个实体类,使用@Document注解标记它为Elasticsearch文档类型,定义索引名称、类型等信息。

java 复制代码
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Document(indexName = "pos_order", createIndex = false)
public class PosOrder {
    
    @Id
    private String id;
    private String customerName;
    private double totalAmount;
    
    // Getter and Setter methods
}

2、创建Elasticsearch Repository

Spring Data Elasticsearch提供了ElasticsearchRepository接口,用于与Elasticsearch进行交互:

java 复制代码
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface PosOrderRepository extends ElasticsearchRepository<PosOrder, String> {
    
    // 你可以根据需求定义其他查询方法
    List<PosOrder> findByCustomerName(String customerName);
}

3、使用Elasticsearch Repository

在你的Service或Controller中注入PosOrderRepository并使用它来进行CRUD操作:

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PosOrderService {

    @Autowired
    private PosOrderRepository posOrderRepository;

    public void saveOrder(PosOrder posOrder) {
        posOrderRepository.save(posOrder);
    }

    public List<PosOrder> findOrdersByCustomerName(String customerName) {
        return posOrderRepository.findByCustomerName(customerName);
    }
}

4、es业务类-使用Elasticsearch模板(可选)

如果需要执行更复杂的查询,可以使用ElasticsearchRestTemplate:

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;

@Service
public class PosOrderService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public void searchOrders() {
        // 自定义查询逻辑
    }
}
  • 通过这些步骤,你可以在Spring Boot项目中轻松地集成Elasticsearch,实现数据的存储、查询等功能。

5、启动测试类

如果你是使用Spring Boot进行开发,确保你的服务已经注入并正常工作。你可以在Spring Boot的启动类或一个控制器中调用测试方法。

例如,在Spring Boot启动类中调用测试方法:

java 复制代码
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootApplication
public class ElasticsearchTestApplication implements CommandLineRunner {

    @Autowired
    private PosOrderService posOrderService;

    public static void main(String[] args) {
        SpringApplication.run(ElasticsearchTestApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // 调用测试方法
        posOrderService.searchOrders();  // 或其他方法,如testIndexDocument(), testSearch(), etc.
    }
}

(二)es提供的客户端库

1、es连接配置类-ElasticSearchConfig

java 复制代码
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @className: ElasticsearchConfig
 * @description: es客户端连接配置类
 * @author: wuyafei
 * @date: 2025/1/16 15:57
 * @version: 1.0
 */
@Configuration
public class ElasticSearchConfig {

	@Value("${elasticsearch.host}")
	private String esHost;

	@Value("${elasticsearch.port}")
	private int esPort;

	@Value("${elasticsearch.scheme}")
	private String esScheme;

	@Value("${elasticsearch.username}")
	private String esUsername;

	@Value("${elasticsearch.password}")
	private String esPassword;

	@Bean
	public RestHighLevelClient client() {
		// 配置基本身份验证的用户名和密码
		BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
		credentialsProvider.setCredentials(AuthScope.ANY,
				new UsernamePasswordCredentials(esUsername, esPassword));

		// 创建一个 HttpAsyncClientBuilder,并设置身份验证
		HttpAsyncClientBuilder asyncClientBuilder = HttpAsyncClients.custom()
				.setDefaultCredentialsProvider(credentialsProvider);

		// 返回 RestHighLevelClient,并通过 setHttpClientConfigCallback 传递 HttpAsyncClientBuilder
		return new RestHighLevelClient(
				RestClient.builder(new HttpHost(esHost, esPort, esScheme))
						.setHttpClientConfigCallback(httpClientConfig -> asyncClientBuilder)
		);
	}

}

注意事项:HTTP与HTTPS:如果Elasticsearch实例使用HTTPS协议,确保修改HttpHost为https,并调整端口(通常是443)

2、es业务类-ElasticSearchService

java 复制代码
package com.hxl.bi.service.es;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

/**
 * @className: ElasticsearchService
 * @description: es查询service
 * @author: wuyafei
 * @date: 2025/1/16 16:27
 * @version: 1.0
 */
@Service
public class ElasticSearchService {

	private final RestHighLevelClient client;

	public ElasticSearchService(RestHighLevelClient client) {
		this.client = client;
	}

	public void searchDocument() throws Exception {
		//创建搜索请求(索引)
		SearchRequest searchRequest = new SearchRequest("bi-pos-order-query-2025");
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		//1、全部查询
		sourceBuilder.query(QueryBuilders.matchAllQuery());
//		//2、精确查询
//		sourceBuilder.query(QueryBuilders.termQuery("orderNo", "6660001250070030004"));
//		//3、范围查询
//		sourceBuilder.query(QueryBuilders.rangeQuery("orderNo").gte(6660001250070030003l).lte(6660001250070030005l));
//		//4、模糊查询
//		sourceBuilder.query(QueryBuilders.fuzzyQuery("orderNo", "6660001250070030004").fuzziness(Fuzziness.ONE));
//		//5、多字段查询
//		sourceBuilder.query(QueryBuilders.multiMatchQuery("hello", "field1", "field2"));
//		//6、布尔查询-boolQuery 允许你组合多个查询,支持 must(必须匹配)、should(可以匹配)、must_not(不能匹配)等操作
//		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
//				.must(QueryBuilders.termQuery("order_id", "123"))
//				.should(QueryBuilders.rangeQuery("total_amount").gte(100))
//				.mustNot(QueryBuilders.termQuery("status", "canceled"));
//		sourceBuilder.query(boolQuery);
//		searchRequest.source(sourceBuilder);
//		//7、存在查询-existsQuery 用于查询某个字段是否存在。常用于检查某个字段是否被填充
//		sourceBuilder.query(QueryBuilders.existsQuery("customer_name"));
//		//8、前缀查询-prefixQuery 用于查询某个字段的前缀匹配。常用于搜索建议
//		sourceBuilder.query(QueryBuilders.prefixQuery("orderId", "ORD"));
//		//9、组合查询-constantScoreQuery 用于组合多个查询,并使用一个权重对它们进行评分。常用于提高查询结果的相关性
//		sourceBuilder.query(QueryBuilders.constantScoreQuery(QueryBuilders.termQuery("status", "active")));
//		//10、聚合查询-aggregation 聚合查询用于对查询结果进行分组和统计。常用于生成报表和统计信息
//		sourceBuilder.aggregation(
//				AggregationBuilders.terms("agg_by_status").field("status.keyword")
//		);
//		//11、排序查询
//		sourceBuilder.sort("total_amount", SortOrder.DESC);  // 根据 `total_amount` 降序排序
		SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
		// 打印查询到的文档总数
		System.out.println("Total hits: " + response.getHits().getTotalHits().value);

		// 获取并打印每个文档的详细内容
		for (SearchHit hit : response.getHits()) {
			// 打印文档的ID
			System.out.println("Document ID: " + hit.getId());

			// 打印文档的源数据 (即文档的实际内容)
			System.out.println("Document Source: " + hit.getSourceAsString());

			// 如果需要进一步处理每个字段,可以通过 hit.getSourceAsMap() 获取字段及其对应的值
			System.out.println("Document Fields: " + hit.getSourceAsMap());
		}
	}

}
  • 上面包含了es查询11个api,按照实际业务需要去适配

3、启动测试类

如果你是使用Spring Boot进行开发,确保你的服务已经注入并正常工作。你可以在Spring Boot的启动类或一个控制器中调用测试方法。

例如,在Spring Boot启动类中调用测试方法:

java 复制代码
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootApplication
public class ElasticsearchTestApplication implements CommandLineRunner {

    @Autowired
    private ElasticSearchService elasticsearchService;

    public static void main(String[] args) {
        SpringApplication.run(ElasticsearchTestApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // 调用测试方法
        elasticsearchService.searchDocument();  // 或其他方法,如testIndexDocument(), testSearch(), etc.
    }
}

五、总结

相关推荐
lihan_freak7 分钟前
MyBatisPlus--分页插件
java·spring boot·mybatis-plus
王景程9 分钟前
Java冒泡排序算法之:变种版
java·数据结构·算法
大G哥20 分钟前
记录一次RPC服务有损上线的分析过程
java·开发语言·网络·网络协议·rpc
camellias_35 分钟前
Springboot(五十八)SpringBoot3使用Redisson实现接口的限流功能
java·spring boot·后端
ruleslol1 小时前
java基础概念56-Stream流
java
C++小厨神1 小时前
Java语言的软件工程
开发语言·后端·golang
ss2731 小时前
基于Springboot + vue实现的旅游网站
vue.js·spring boot·旅游
Jackson@ML2 小时前
2025最新版IntelliJ IDEA for Mac安装使用指南
java·macos·intellij-idea
梦浪流云2 小时前
RK3576 Android14 状态栏和导航栏增加显示控制功能
android·java
Suwg2092 小时前
《手写Mybatis渐进式源码实践》实践笔记(第九章 细化XML语句构建器)
xml·java·笔记·mybatis