ElasticSearch业务场景与面试题

server/2025/2/9 6:19:46/

以下是几个常见的 Elasticsearch 业务场景解决方案及面试题解析(含 Java 示例):


一、业务场景解决方案


场景 1:商品搜索与过滤

需求:电商平台需要支持多条件搜索(关键词、价格区间、分类、品牌)并按相关性排序。

解决方案

  1. Bool Query:组合 must(必须匹配)、should(加分项)、filter(无评分过滤)。
  2. Keyword 字段:分类/品牌等精确匹配字段使用 keyword 类型。
  3. 范围查询:价格区间使用 range 查询。
  4. 相关性排序:使用 TF-IDF 或 BM25 算法(ES 默认)。
// 使用 RestHighLevelClient(旧版)或 Java Client(新版)
SearchRequest request = new SearchRequest("products");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name", "手机")) // 关键词匹配.filter(QueryBuilders.rangeQuery("price").gte(1000).lte(5000)) // 价格过滤.filter(QueryBuilders.termQuery("category", "electronics")) // 分类精确匹配.should(QueryBuilders.matchQuery("brand", "Apple").boost(2.0f)); // 品牌加分sourceBuilder.query(boolQuery).sort(SortBuilders.scoreSort()) // 按相关性排序.from(0).size(10); // 分页request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);

场景 2:日志分析与聚合

需求:分析系统日志中不同错误级别的出现次数。

解决方案

  1. Date Histogram:按时间区间聚合。
  2. Terms Aggregation:按错误级别分组统计。
  3. 索引设计:使用 @timestamp 字段记录日志时间。
SearchRequest request = new SearchRequest("logs");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();// 按错误级别聚合
TermsAggregationBuilder termsAgg = AggregationBuilders.terms("error_levels").field("level");
// 子聚合:按小时统计
DateHistogramAggregationBuilder dateHistogram = AggregationBuilders.dateHistogram("per_hour").field("@timestamp").calendarInterval(DateHistogramInterval.HOUR);termsAgg.subAggregation(dateHistogram);
sourceBuilder.aggregation(termsAgg);request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 解析聚合结果
Terms terms = response.getAggregations().get("error_levels");
for (Terms.Bucket bucket : terms.getBuckets()) {String level = bucket.getKeyAsString();DateHistogram dateHistogramAgg = bucket.getAggregations().get("per_hour");for (DateHistogram.Bucket hourBucket : dateHistogramAgg.getBuckets()) {System.out.println(level + " - " + hourBucket.getKeyAsString() + ": " + hourBucket.getDocCount());}
}

场景 3:搜索自动补全

需求:实现类似 Google 的搜索框自动补全功能。

解决方案

  1. Completion Suggester:专为自动补全设计的字段类型。
  2. N-gram 分词:支持部分匹配(如 “el” 匹配 “elasticsearch”)。
// 创建索引时定义补全字段
CreateIndexRequest request = new CreateIndexRequest("suggestions");
request.mapping("{\n" +"  \"properties\": {\n" +"    \"suggest\": {\n" +"      \"type\": \"completion\"\n" +"    }\n" +"  }\n" +"}",XContentType.JSON
);
client.indices().create(request, RequestOptions.DEFAULT);// 查询时使用 Suggest
SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("my_suggestion",new CompletionSuggestionBuilder("suggest").prefix("el").size(5));SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().suggest(suggestBuilder);
SearchRequest searchRequest = new SearchRequest("suggestions").source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析补全结果
CompletionSuggestion suggestion = response.getSuggest().getSuggestion("my_suggestion");
for (CompletionSuggestion.Entry.Option option : suggestion.getOptions()) {System.out.println(option.getText().string());
}

二、高频面试题


问题 1:Elasticsearch 如何保证数据一致性?
  • :ES 是近实时(NRT)系统,默认每秒刷新(refresh)一次。写入数据后需等待刷新或手动调用 refresh 才能搜索到。通过 wait_for 参数可强制等待变更可见:
    IndexRequest request = new IndexRequest("index").source("field", "value").setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
    

问题 2:如何处理深度分页的性能问题?
  • :避免使用 from + size(如 from=10000),改用 search_after
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().sort(SortBuilders.fieldSort("_id")) // 必须包含唯一排序字段.size(10);// 第一次查询
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    SearchHit[] hits = response.getHits().getHits();// 后续分页使用 search_after
    sourceBuilder.searchAfter(hits[hits.length - 1].getSortValues());
    

问题 3:如何同步 MySQL 数据到 Elasticsearch?
  • 方案
    1. Logstash JDBC Input:定时拉取 MySQL 数据。
    2. Binlog 监听:使用 Canal 或 Debezium 捕获 MySQL 变更,通过 Kafka 同步到 ES。
    3. 双写:应用层直接写入 MySQL 和 ES(需处理事务一致性)。

问题 4:如何优化 Elasticsearch 集群性能?
    • 硬件:使用 SSD、增加内存。
    • 索引设计:合理设置分片数(建议单个分片 10-50GB)、关闭不需要的字段 norms
    • 查询优化:避免通配符查询、使用 filter 替代 query 避免评分。
    • 冷热分离:将历史数据迁移到冷节点。

三、陷阱与注意事项

  1. 分片数不可变:创建索引时需预先规划分片数量。
  2. 脑裂问题:通过 discovery.zen.minimum_master_nodes(旧版)或 cluster.initial_master_nodes(新版)配置避免。
  3. 映射爆炸:限制动态映射,避免过多字段导致内存问题。

以上内容覆盖了常见场景和面试考点,结合 Java 代码可快速实现功能验证。


http://www.ppmy.cn/server/166142.html

相关文章

P1049 装箱问题(dp)

#include<bits/stdc.h> using namespace std;int main() {int v,n;cin>>v>>n;int a[30];int dp[20005];for(int i0;i<n;i){cin>>a[i];}memset(dp,0,sizeof(dp));// 设置所有元素为0&#xff0c;表示最大体积为0for(int i0;i<n;i){for(int jv;j&…

redis之GEO 模块

文章目录 背景GeoHash 算法redis中的GeoHash 算法基本使用增加距离获取元素位置获取元素的 hash 值附近的元素 注意事项原理 背景 如果我们有需求需要存储地理坐标&#xff0c;为了满足高性能的矩形区域算法&#xff0c;数据表需要在经纬度坐标加上双向复合索引 (x, y)&#x…

图文并茂-jvm内存模型

堆内存划分的空间&#xff0c;如何回收这些内存对象&#xff0c;有哪些回收算法&#xff1f; 推荐阅读 设计模式与技术组件图解Java类文件到虚拟机-CSDN博客

【AcWing】蓝桥杯辅导课-二分与前缀和

目录 二分 数的范围 数的三次方跟 机器人跳跃问题 四平方和 分巧克力 前缀和 前缀和 子矩阵的和 K倍区间 激光炸弹 二分 数的范围 789. 数的范围 - AcWing题库 #include<iostream> using namespace std;const int N 1e5 10;int n, q, k, a[N];int main()…

COBOL语言的云计算

COBOL语言与云计算&#xff1a;重新定义传统编程的未来 引言 在技术迅速发展的今天&#xff0c;云计算已成为推动企业数字化转型的关键力量。与此同时&#xff0c;许多传统编程语言依然在大型企业中发挥着不可或缺的作用。在这些传统语言中&#xff0c;COBOL&#xff08;Comm…

101.对称二叉树 python

对称二叉树 题目题目描述示例 1&#xff1a;示例 2&#xff1a;提示&#xff1a; 题解递归法步骤提交结果 迭代法步骤提交结果 题目 题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出…

微信小程序地图开发总结-规划路线

在现代移动应用中&#xff0c;地图导航功能已成为必不可少的一部分。通过地图 API&#xff0c;我们可以轻松地在应用中集成位置服务和路径规划功能。本篇文章将带大家一起实现一个简单的路径导航功能&#xff0c;使用腾讯地图 API结合微信小程序&#xff0c;实现从当前位置到目…

企业FTP替代升级,实现传输大文件提升100倍!

随着信息技术的飞速发展&#xff0c;网络安全环境也变得越来越复杂。在这种背景下&#xff0c;传统的FTP&#xff08;文件传输协议&#xff09;已经很难满足现代企业对文件传输的需求了。FTP虽然用起来简单&#xff0c;但它的局限性和安全漏洞让它在面对高效、安全的数据交换时…