Spring Boot 整合 Elasticsearch 及实战应用

简介: 这次内容详细介绍如何使用 Spring Boot 整合 Elasticsearch,并提供几个实际应用案例。内容涵盖 Elasticsearch 的基本概念、Spring Boot 整合步骤、实战应用示例以及优化建议。

这次内容详细介绍如何使用 Spring Boot 整合 Elasticsearch,并提供几个实际应用案例。内容涵盖 Elasticsearch 的基本概念、Spring Boot 整合步骤、实战应用示例以及优化建议。

1、Elasticsearch 概念及作用

Elasticsearch 是一个基于 Apache Lucene 构建的分布式、RESTful 风格的搜索和数据分析引擎。它专门为处理大规模数据而设计,提供近实时的搜索能力,支持结构化、全文、地理空间等多种类型的查询。

核心特性与作用包括:

  • 分布式架构:支持水平扩展,通过分片(Shard)和副本(Replica)机制实现高可用与负载均衡。
  • 近实时搜索:数据索引后几乎立即可搜,适用于需要快速响应的场景。
  • 强大的全文搜索:基于倒排索引,支持复杂的查询、高亮显示、模糊匹配等。
  • 数据分析与聚合:提供丰富的聚合功能(Aggregations),用于对数据进行统计和分析。
  • 多类型数据支持:除了文本,还能处理日志、指标、地理空间数据等。
  • 易用性与扩展性:提供 RESTful API,支持多种编程语言集成,并拥有活跃的生态系统。

Elasticsearch 广泛应用于电商搜索、日志分析、实时监控、数据可视化等领域。

2、Spring Boot 整合 Elasticsearch

2.1、环境准备与依赖配置

在 Spring Boot 项目中,首先需要在 pom.xml 中添加 Elasticsearch 相关依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

在 application.properties 中配置 Elasticsearch 连接信息:

spring.elasticsearch.rest.uris=http://localhost:9200
spring.data.elasticsearch.repositories.enabled=true

如果连接 Elasticsearch 集群,可以配置集群名称和节点:

spring.data.elasticsearch.cluster-name=your-cluster-name
spring.data.elasticsearch.cluster-nodes=ip1:port1,ip2:port2

2.2、创建 Elasticsearch 实体类

使用 @Document 注解定义一个实体类,映射到 Elasticsearch 的索引:

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@Document(indexName = "articles")
public class Article {
    @Id
    private String id;
    private String title;
    private String content;
    
    // 无参构造器、有参构造器、getter和setter方法
    public Article() {}
    
    public Article(String id, String title, String content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }
    
    // Getter 和 Setter 方法
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
}

2.3、创建 Elasticsearch Repository

创建一个继承 ElasticsearchRepository 的接口,用于数据操作:

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {
    
    // 根据内容进行全文搜索
    List<Article> findByContentContaining(String content);
    
    // 根据标题搜索
    List<Article> findByTitleContaining(String title);
}

2.4、控制器层实现

创建一个 REST 控制器来处理搜索请求:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/articles")
public class ArticleController {
    
    @Autowired
    private ArticleRepository articleRepository;
    
    // 搜索文章
    @GetMapping("/search")
    public List<Article> searchArticles(@RequestParam String query) {
        return articleRepository.findByContentContaining(query);
    }
    
    // 添加新文章
    @PostMapping
    public Article createArticle(@RequestBody Article article) {
        return articleRepository.save(article);
    }
}

3、Elasticsearch 实战应用案例

3.1、案例一:电商平台商品搜索与高亮显示

业务场景:电商平台需要为用户提供高效的商品搜索功能,在海量数据中快速返回匹配结果,并高亮显示关键字。

实现步骤

  1. 创建商品索引: 使用 Elasticsearch 的 REST API 创建商品索引:
PUT /products
   {
     "mappings": {
       "properties": {
         "name": { "type": "text" },
         "description": { "type": "text" },
         "price": { "type": "float" }
       }
     }
   }
  1. 添加商品数据
POST /products/_doc/1
   {
     "name": "华为 Mate 70",
     "description": "Mate 70 手机是搭载纯血鸿蒙NEXT 系统的第一款旗舰机",
     "price": 6500
   }
  1. 实现搜索与高亮: 在 Repository 中定义复杂查询方法:
import org.springframework.data.elasticsearch.annotations.Query;
   import java.util.List;
   
   public interface ProductRepository extends ElasticsearchRepository<Product, String> {
       
       @Query("{\"multi_match\": {\"query\": \"?0\", \"fields\": [\"name\", \"description\"]}}")
       List<Product> findByQuery(String query);
   }

使用 Elasticsearch 的高亮查询:

@Service
   public class ProductService {
       
       @Autowired
       private ElasticsearchRestTemplate elasticsearchTemplate;
       
       public List<SearchHit<Product>> searchProductsWithHighlight(String keyword) {
           // 创建查询条件
           NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
               .withQuery(QueryBuilders.multiMatchQuery(keyword, "name", "description"))
               .withHighlightFields(
                   new HighlightBuilder.Field("name").preTags("<em>").postTags("</em>"),
                   new HighlightBuilder.Field("description").preTags("<em>").postTags("</em>")
               )
               .build();
           
           SearchHits<Product> searchHits = elasticsearchTemplate.search(searchQuery, Product.class);
           return searchHits.getSearchHits();
       }
   }

3.2、案例二:日志收集与分析系统

业务场景:对分布式系统中的应用日志进行集中管理、实时监控与分析,快速定位系统错误和性能瓶颈。

解决方案

  1. 使用 ELK/EFK 技术栈
  • Filebeat/Logstash:收集应用日志
  • Elasticsearch:存储和索引日志数据
  • Kibana:日志可视化和监控


  1. 创建日志索引


  1. 实现日志分析
public interface LogRepository extends ElasticsearchRepository<AppLog, String> {
       
       // 统计各日志级别的数量
       @Query("{\"aggs\": {\"levels\": {\"terms\": {\"field\": \"level.keyword\"}}}}")
       AggregatedPage<AppLog> countByLevel();
       
       // 根据时间范围查询日志
       List<AppLog> findByTimestampBetween(String startTime, String endTime);
   }

3.3、案例三:复杂查询与聚合分析

业务场景:新闻分析平台需要对大量文章进行复杂查询和内容分析,例如统计特定关键词的出现频率。

实现方案

  1. 布尔查询: 组合多个查询条件:
import org.elasticsearch.index.query.QueryBuilders;
   import org.elasticsearch.index.query.BoolQueryBuilder;
   
   public List<Article> complexSearch(String mustTerm, String shouldTerm, String mustNotTerm) {
       BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
           .must(QueryBuilders.matchQuery("title", mustTerm))
           .should(QueryBuilders.matchQuery("content", shouldTerm))
           .mustNot(QueryBuilders.matchQuery("status", mustNotTerm));
       
       NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
           .withQuery(boolQuery)
           .build();
       
       return elasticsearchTemplate.search(searchQuery, Article.class).getContent();
   }
  1. 聚合分析: 统计标签出现频率:
public void tagAggregation() {
       TermsAggregationBuilder aggregation = AggregationBuilders
           .terms("tags_aggregation")
           .field("tags.keyword");
       
       NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
           .addAggregation(aggregation)
           .build();
       
       SearchHits<Article> searchHits = elasticsearchTemplate.search(searchQuery, Article.class);
       Terms terms = searchHits.getAggregations().get("tags_aggregation");
       
       for (Terms.Bucket bucket : terms.getBuckets()) {
           System.out.println("标签: " + bucket.getKey() + ", 数量: " + bucket.getDocCount());
       }
   }

4、性能优化建议

  1. 索引优化
  • 为常用字段建立合适的索引映射
  • 根据数据类型选择合适的分析器


  1. 查询优化
  • 使用过滤器缓存结果
  • 限制检索范围,避免全索引扫描
  • 使用分页减少返回数据量


  1. 集群与分片配置
  • 根据数据量和硬件配置合理设置分片数量和副本
  • 监控节点负载,避免热点数据问题


  1. 批量操作: 对于大量数据插入和更新,使用批量操作提高效率:
@Service
   public class BulkOperationService {
       
       @Autowired
       private ElasticsearchRestTemplate elasticsearchTemplate;
       
       public void bulkInsert(List<Article> articles) {
           List<IndexQuery> queries = articles.stream()
               .map(article -> new IndexQueryBuilder()
                   .withId(article.getId())
                   .withObject(article)
                   .build())
               .collect(Collectors.toList());
           
           elasticsearchTemplate.bulkIndex(queries, BulkOptions.defaultOptions());
       }
   }

5、总结

主要介绍了 Spring Boot 与 Elasticsearch 的整合方法,并通过电商搜索、日志分析和复杂查询三个实际案例展示了 Elasticsearch 的应用价值。通过合理的配置和优化,Elasticsearch 能够为应用程序提供强大的搜索和数据分析能力,满足大数据量下的高性能需求。

Elasticsearch 的分布式特性和丰富的功能集使其成为现代应用中不可或缺的搜索和分析引擎,合理利用其特性可以显著提升应用的搜索体验和数据处理能力。

Spring Boot 整合 Elasticsearch 及实战应用.png

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。


您的一键三连,是我更新的最大动力,谢谢

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

相关文章
|
7天前
|
数据采集 人工智能 安全
|
16天前
|
云安全 监控 安全
|
2天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
266 155
|
3天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:六十九、Bootstrap采样在大模型评估中的应用:从置信区间到模型稳定性
Bootstrap采样是一种通过有放回重抽样来评估模型性能的统计方法。它通过从原始数据集中随机抽取样本形成多个Bootstrap数据集,计算统计量(如均值、标准差)的分布,适用于小样本和非参数场景。该方法能估计标准误、构建置信区间,并量化模型不确定性,但对计算资源要求较高。Bootstrap特别适合评估大模型的泛化能力和稳定性,在集成学习、假设检验等领域也有广泛应用。与传统方法相比,Bootstrap不依赖分布假设,在非正态数据中表现更稳健。
206 105
|
10天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
724 5
|
13天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
814 153