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.
    }
}

五、总结

相关推荐
不会Hello World的小苗18 分钟前
Java——列表(List)
java·python·list
二十七剑1 小时前
jvm中各个参数的理解
java·jvm
东阳马生架构3 小时前
JUC并发—9.并发安全集合四
java·juc并发·并发安全的集合
Elastic 中国社区官方博客3 小时前
Elasticsearch Open Inference API 增加了对 Jina AI 嵌入和 Rerank 模型的支持
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索·jina
计算机小白一个3 小时前
蓝桥杯 Java B 组之岛屿数量、二叉树路径和(区分DFS与回溯)
java·数据结构·算法·蓝桥杯
孤雪心殇3 小时前
简单易懂,解析Go语言中的Map
开发语言·数据结构·后端·golang·go
隔壁老王1563 小时前
mysql实时同步到es
数据库·mysql·elasticsearch
White graces3 小时前
正则表达式效验邮箱格式, 手机号格式, 密码长度
前端·spring boot·spring·正则表达式·java-ee·maven·intellij-idea
菠菠萝宝3 小时前
【Java八股文】10-数据结构与算法面试篇
java·开发语言·面试·红黑树·跳表·排序·lru
不会Hello World的小苗3 小时前
Java——链表(LinkedList)
java·开发语言·链表