当前位置: 首页 > news >正文

Elasticsearch搜索机制与分页优化策略

引言

Elasticsearch的搜索性能依赖于其分布式架构与混合索引设计:

  1. 两阶段查询:协调节点通过Query阶段并行筛选分片结果(基于文档ID与排序值),再经Fetch阶段精准拉取全量数据;
  2. 混合索引加速:BKD树(数值/日期字段)实现高效范围查询(O(log N)),倒排索引(字符串字段)支持快速关键词匹配;
  3. 海量数据分页:突破max_result_window默认限制需权衡内存开销,而Scroll API(批量拉取)与Search After(动态分页)分别适用于离线分析与实时场景。

全文解析搜索链路核心逻辑,为高并发场景提供性能优化方向。

文档搜索的过程

Query阶段

  • Client 将请求发送到任意节点 node,此时 node 节点就是协调节点(coordinating node)。
  • 协调节点进行分词等操作后,去查询所有的分片(主分片和副本分片选择一个)。
  • 所有分片将满足条件的文档 ID、排序字段的值等信息返回给协调节点。
  • 协调节点重新进行排序,截取数据后,获取到真正需要返回的数据的 id。

Fetch阶段

  • 协调节点再次请求对应的分片 (此时有 id 了,可以直接定位到对应分片)。
  • 获取到全量数据,返回给 Client。

多条件搜索过程

{"query": {"bool": {"must": [{"match": {"brand": "BrandA"}},{"range": {"price": {"lt": 800}}},{"term": {"available": true}}]}}
}

协调节点会将所有查询条件并行的分发到所有的数据节点,每个节点在其本地的分片上执行词项查找。最后得到多个集合,对多个集合取并集得出满足条件的文档ID,在进行Fetch阶段操作。

注:index.max_result_window默认10000,搜索请求返回文档数量限制,返回文档数超过配置则报错。

文档搜索是否会跳过Fetch阶段?

是否需要进入 Fetch 阶段取决于查询请求的具体配置。如果查询请求只需要文档ID、特定字段或进行聚合计算,则可以跳过 Fetch 阶段。

范围查询为什么会高效?

数值类型日期类型字段并不是使用倒排索引结构存储的,而是使用BKD树结构存储的。这种结构特别适合处理范围查询和排序操作,因为它能够高效地进行数值范围搜索、排序以及聚合操作。

字符串类型字段是使用倒排索引结构存储的。

什么是BKD树

K-D-B树是K-D树与B树的结合,而B-K-D树是基于K-D-B树设计的。

高效的原因

  1. 采用BKD数据结构存储数值、日期类型,BKD又有B树的影子所以范围查询效率高。
  2. 分布式架构设计,可以同时在多个分片上进行范围查询,最后在协调节点进行汇总。

如何处理返回大结果集的搜索请求?

Elasticsearch 会通过index.max_result_window配置(默认10000)限制返回结果集大小,在分页查询中from + size超过配置也会报错。

调大index.max_result_window配置

  • 优点:可以允许 Elasticsearch 返回更多的结果,从而支持更大范围的分页查询。
  • 缺点:每次查询返回的结果集变大,这会增加 Elasticsearch 的内存占用。处理查询时花费更多的时间,特别是在数据量非常大的情况下,查询效率可能会明显下降。

使用Scroll Api查询

每次查询都会返回scroll_id字段,下次查询时把scroll_id传进去继续查询,直到hits为空则不在进行查询,hits是实际返回的数据。

  • 优点适用于从单个搜索请求中检索大量数据,类似于数据库中的游标,可以遍历所有结果;性能较稳定,尤其是在大规模数据集上。
  • 缺点:不适合实时性要求高的场景,因为每次执行 scroll 操作时,数据快照会固定在查询初始时的状态,不能实时反映数据的更新。

使用Search After查询

下次查询时,需要提供上一页最后一条记录的排序信息。如果排序值不唯一下次查询时会产生重复数据。

  • 优点适用于深度分页,能实现实时性要求较高的查询,每次请求都是独立的,并能处理数据的实时更新。从上一个查询结果的最后一个文档开始检索,避免了深分页时的性能问题。
  • 缺点:需要有一个唯一且可排序的字段来实现分页,可能会对查询性能有影响,并且只能是一页一页的向后翻。

感谢您的阅读!如果文章中有任何问题或不足之处,欢迎及时指出,您的反馈将帮助我不断改进与完善。期待与您共同探讨技术,共同进步!

http://www.xdnf.cn/news/681697.html

相关文章:

  • Pytest自动化测试框架搭建:Jenkins持续集成
  • 通俗解释网络参数RTT(往返时间)
  • Scratch节日 | 六一儿童节
  • 并发编程(二)—synchronized和volatile
  • 尚硅谷redis7 55-57 redis主从复制之理论简介
  • 从零搭建上门做饭平台:高并发订单系统设计
  • 普罗米修斯监控CPU\内存汇聚图
  • 产业集群间的专利合作关系
  • Visual Studio编译当前文件
  • vue项目 build时@vue-office/docx报错
  • ceph recovery 相关参数
  • MMdetection推理验证输出详解(单张图片demo)
  • 用DEEPSEEK写的扫雷小游戏
  • 如何设计高效的索引策略?
  • 一则doris数据不一致问题
  • Day38 Python打卡训练营
  • Python+OpenCV实战:高效实现车牌自动识别
  • 卷积神经网络(CNN)入门学习笔记
  • 定时清理流媒体服务器录像自动化bash脚本
  • 大模型 Agent 中的通用 MCP 机制详解
  • JavaScript- 4.1 DOM-document对象
  • FEMFAT许可的常见问题及解决方案
  • 【慧游鲁博】【10】全端优化用户信息存储+网页端user模块与后端对接
  • AI一周事件(2025年5月20日-5月26日)
  • 使用API有效率地管理Dynadot域名,查看一口价域名的详细信息
  • 伪创新-《软件方法》全流程引领AI-第1章 04
  • JavaScript 中 this 指向详解
  • 2025年我国低空经济产业链研究与梳理
  • P2 C++基础(2.2)
  • minhash-大模型输入前的去重