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

为什么ES中不推荐使用wildcard查询

在lucene中AutomatonQuery类的作用中,我们说了 AutomatonQuery 性能很高。
那么,为什么 Elasticsearch 的官方文档和所有最佳实践都强烈建议不要使用前缀通配符(leading wildcard),比如 *text

答案在于 AutomatonQuery 的高效是有条件的,而前缀通配符恰好破坏了这个条件。


核心原因:与有序词项词典(Term Dictionary)的交互方式

Lucene 的性能秘诀在于它的倒排索引,其中一个关键部分是词项词典(Term Dictionary)。这个词典存储了索引中所有唯一的词项,并且是按字典序(alphabetically)排序的

这个“按字典序排序”的特性至关重要。我们来对比两种通配符查询:

1. 后缀通配符查询(Trailing Wildcard)- 性能很高 (text*)

当你执行一个像 text* 这样的查询时:

  1. 构建自动机:Lucene 构建一个自动机,它匹配以 text 开头的任何字符串。
  2. 遍历词典:由于词典是按字典序排序的,所有以 text 开头的词项(如 textbook, testing, texture)都连续地存放在一起
  3. 高效查找:Lucene 的查询执行器可以非常高效地:
    • **直接定位(Seek)**到词典中第一个以 text 开头的词项。这就像在字典里查 “text” 这个单词一样快。
    • 然后,它只需要顺序扫描该位置之后的少量词项,直到遇到第一个不以 text 开头的词项为止。
    • 整个过程非常快,因为它只需要检查词典中一个很小的、连续的片段。

这正是 AutomatonQuery 高性能的典型场景。

2. 前缀通配符查询(Leading Wildcard)- 性能灾难 (*text)

当你执行一个像 *text 这样的查询时:

  1. 构建自动机:Lucene 构建一个自动机,它匹配以 text 结尾的任何字符串。
  2. 遍历词典:问题来了。因为词典是按开头字母排序的,所以以 text 结尾的词项(如 context, subtext, hypertext)会分散在整个词典的各个角落
  3. 低效查找:为了找到所有匹配项,AutomatonQuery 别无选择,只能:
    • 从词典的第一个词项(比如 “a”)开始。
    • 逐个检查词典中的每一个词项,看它是否以 text 结尾。
    • 这个过程会一直持续到词典的最后一个词项

这相当于对整个字段的词项词典进行了一次全量扫描(Full Scan)

这为什么在 Elasticsearch 中是灾难性的?

  • 规模放大:一个 Lucene 索引(在 ES 中称为分片/Shard)的词项词典可能包含数百万甚至数千万个唯一词项。对单个分片进行全量扫描已经非常耗费 CPU。
  • 分布式特性:一个 Elasticsearch 索引通常由多个分片组成,这些分片分布在集群的多个节点上。当你执行一个 *text 查询时,这个全量扫描的操作会在所有相关的分片上并行执行
  • 集群影响:这个查询会瞬间占用大量 CPU 资源,导致集群的查询延迟飙升,影响所有其他正在进行的查询,甚至可能因为负载过高而导致节点不稳定。它被称为“Query of Death”(死亡查询)之一。

总结:理论与实践的鸿沟

  • 理论上AutomatonQuery 本身是一个高效的算法。
  • 实践中:它的性能高度依赖于它所操作的数据结构。当与一个有序的词典结合使用时,对于前缀友好的模式(如 text*),它可以利用“有序”这一特性进行快速定位,性能极高。但对于前缀不友好的模式(如 *text),它无法利用“有序”特性,被迫退化为全量扫描,性能极差。

Elasticsearch 作为一个大规模、多租户的系统,必须优先保证整个集群的稳定性和性能。因此,它强烈建议避免那些会导致资源浩劫的操作,而前缀通配符查询正是其中的典型代表。


那么,如何解决需要匹配“中间”或“结尾”的需求?

既然直接用 *text 不行,Elasticsearch 社区发展出了一些标准的解决方案,核心思想是在索引时做一些额外的工作,将慢查询转换为快查询

  1. reverse Token Filter(反转词元过滤器)
    这是解决前缀通配符最经典的方法。

    • 索引时:对原始词项(如 context)建立一个反转后的版本(txetnoc)并存入另一个子字段。
    • 查询时:当用户想搜 *text 时,你将查询条件反转为 txet*,然后去查询那个反转后的字段。
    • 效果:一个慢速的、全量扫描的前缀通配符查询,变成了一个高速的、可以快速定位的后缀通配符查询
  2. n-gram Token Filter(N元分词过滤器)

    • 索引时:将一个词项(如 text)拆分成一系列的小片段(n-grams)。例如,2-grams 会拆成 te, ex, xt;3-grams 会拆成 tex, ext
    • 查询时:当用户搜索 *text**tex* 时,可以被转换为对 tex 这个 n-gram 的精确匹配查询,速度非常快。
    • 缺点:会极大地增加索引的体积。

AutomatonQuery 本身是把好刀,但用它来砍一个四处分散的目标(前缀通配符),就只能把整个场地犁一遍了。而用它来砍一个整齐排列的目标(后缀通配符),则快如闪电。Elasticsearch 的建议正是基于这种实际应用场景的深刻理解。

http://www.dtcms.com/a/470534.html

相关文章:

  • 怎么叫人做网站高端的网站推广
  • ICT 数字测试原理 18 - -VCL如何对设备进行预处理
  • 19-基于STM32的人体体征监测系统设计与实现
  • 第12讲:深入理解指针(2)——指针的“安全锁”与“传址魔法”
  • 小企业网站制作wordpress 搭建个人博客
  • 企石镇做网站中国建筑装饰网饶明富
  • 深入洞察:从巴菲特投资哲学萃取最佳实践
  • 设计网站的功能有哪些微营销工具
  • 我的世界做皮肤的网站西安市高新区建设局网站
  • 车载360环视平台:米尔RK3576开发板支持12路低延迟推流
  • 松下机械手焊机气体流量调节
  • x64dbg破解学习(浅尝)
  • RRC状态机:移动通信网络中的连接灵魂
  • LibreCAD 编译详细步骤指南
  • 2025年100道最新软件测试面试题,常见面试题及答案汇总
  • (15)100天python从入门到拿捏《面向对象编程》
  • Spring AI Alibaba 与 Ollama 集成初探:从环境搭建到首次调用
  • 营销型网站的标准网站flash导入页
  • 汉中专业网站建设开发怎么上国外网站
  • Windows上离线安装 PostgreSQL
  • MySQL——表的操作
  • langchain官网翻译:Build a Question/Answering system over SQL data
  • 我的HarmonyOS百宝箱
  • 广州十大室内设计公司排名网站推广seo教程
  • h5网站用什么软件做网站域名备案证书下载
  • 南京本地网站有哪些做网页需要什么
  • 机器学习破解生命之谜:内在无序蛋白质设计迎来革命性突破
  • Springboot之常用注解
  • 从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 14--二次开发--封装公共方法 2
  • 做平面的公司网站DNF做钓鱼网站