背景

做搜索或读 Elasticsearch/Lucene 相关代码时,会不断碰到各种 Query。它们不是「SQL 的 where 语法糖」那么简单:每种 Query 对应不同的 匹配语义执行计划(是否可走倒排、是否要自动机、是否要算分等)。

常见 Query 类型

Lucene 里常见的包括:

类型 大致用途
TermQuery 精确 term
BooleanQuery 多子句布尔组合
PhraseQuery / MultiPhraseQuery 短语、多短语
PrefixQuery 前缀
WildcardQuery 通配
FuzzyQuery 模糊(编辑距离)
RegexpQuery 正则
TermRangeQuery / PointRangeQuery 词项/数值点范围
ConstantScoreQuery 固定分
DisjunctionMaxQuery 多查询取 max 分
MatchAllDocsQuery 全匹配

它们大都继承抽象类 Query,再按能力向上抽象出 MultiTermQuery 等中间层。可以组合使用,例如 Boolean 里嵌 Term + Phrase。

继承链:以 RegexpQuery 为例

RegexpQuery 的继承关系大致是:

Query
  └── MultiTermQuery
        └── AutomatonQuery
              └── RegexpQuery

含义:

  1. Query
    抽象根:重写、访问权重、创建 Weight/Scorer 的模板。

  2. MultiTermQuery
    「一个字段上由多个 term 组成的匹配」。通配、前缀、正则、模糊都可能落到「先枚举 term 再合成」的路径。子类要实现如何从 term 字典枚举。

  3. AutomatonQuery
    自动机(Automaton) 描述可接受的 term 集合,在 term 字典上做高效求交/枚举。正则、部分通配会先编译成自动机。

  4. RegexpQuery
    把用户正则编译为自动机,再交给 AutomatonQuery 执行。

因此读 RegexpQuery 源码时,真正的「怎么搜」往往在父类的枚举与 Weight 构建里,子类更偏 构造与正则→自动机

使用上的注意

建议的阅读顺序

  1. TermQuery / BooleanQuery(主干)
  2. MultiTermQuery 的枚举接口
  3. AutomatonQuery + RegexpQuery
  4. 再看 IndexSearcher 如何建 Weight

小结

Lucene Query 体系是「语义 → 可执行结构」的分层。RegexpQuery 不是孤立类,而是 正则 → 自动机 → 多 term 枚举 → 打分 链路上的一环。抓住继承关系,源码阅读会顺很多。

实践建议

和安全的交界

搜索入口若直接拼接用户输入到查询 DSL,可能出现查询注入或昂贵表达式 DoS。应将用户检索词映射到受控 Query 构造器,而不是字符串拼接。

小结

读懂 Query 继承树,是读搜索引擎与加固搜索入口的共同基础。从 Term/Boolean 开始,再进自动机类查询,路径最稳。

调试技巧

构造最小索引(几个文档几个字段),对目标 Query 打印改写后的布尔结构或使用 Luke 等工具看 term。比直接在生产 ES 上试验更安全、更快。

延伸阅读与实践

把文章里的命令和配置放到自己的实验环境跑一遍,比只看结论更重要。建议同步记录:环境版本、失败现象、最终生效的配置。下次遇到同类问题时,检索自己的笔记往往比搜引擎更快。

若该主题涉及安全测试,请仅在明确授权的系统或官方靶场中操作,并保留测试范围与时间窗记录,避免对生产造成误伤。

对团队分享时,用「问题—影响—修复—验证」四段结构复述,有助于把个人经验沉淀为组织能力。