<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>布尔查询 on 极限科技 | INFINI Labs</title><link>https://infinilabs.cn/tags/%E5%B8%83%E5%B0%94%E6%9F%A5%E8%AF%A2/</link><description>Recent content in 布尔查询 on 极限科技 | INFINI Labs</description><generator>Hugo -- gohugo.io</generator><lastBuildDate>Fri, 28 Aug 2026 11:00:00 +0800</lastBuildDate><atom:link href="https://infinilabs.cn/tags/%E5%B8%83%E5%B0%94%E6%9F%A5%E8%AF%A2/index.xml" rel="self" type="application/rss+xml"/><item><title>Easysearch 布尔查询子句重排序（四）｜Block-Max、实战与验证</title><link>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-4/</link><pubDate>Fri, 28 Aug 2026 11:00:00 +0800</pubDate><guid>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-4/</guid><description>Block-Max WAND 块级剪枝、混合查询端到端追踪、Profile API 亲手验证
INFINI Easysearch 是一款专注于企业级场景的分布式近实时搜索与分析引擎。它以 Apache Lucene 为内核进行了增强，在保持与行业主流搜索协议及开发生态完全兼容的同时，重点强化了安全性、稳定性、压缩率及信创兼容性。
引言：从标准 WAND 到块级剪枝 # 前三篇我们走完了 Easysearch 布尔查询优化的前半程： 第一篇讲 rewrite 11 条规则， 第二篇讲合取的 cost 排序， 第三篇讲析取的 WAND 算法——用 maxScore 上界 + 三堆调度，把&amp;quot;上界够不到及格线的文档&amp;quot;在打分前就剪掉。
但标准 WAND 留了个明显短板：每个子句的上界是全局的——&amp;ldquo;这个词在全索引最多能打多少分&amp;rdquo;。游标走到低分文档区，上界仍按全局最高估，剪枝不够激进。本文就围绕这块补全，并把前面所有内容串起来做实战和验证：
一 Block-Max WAND——把全局上界换成&amp;quot;按块分段&amp;quot;的上界，整块低分文档一次跳过 二 实战——MUST + SHOULD 混合查询的端到端追踪，看前几篇内容怎么协作 三 Profile API——用对比实验亲手验证 WAND 生效，避开常见误读 四 开发者启示 五 全系列总结 一、Block-Max WAND 的增强 # 1.1 一个类比：为什么全局上界会&amp;quot;过乐观&amp;quot; # 想象一场考试，每个学生最多能考 100 分。现在老师想知道&amp;quot;有没有人超过 90 分&amp;quot;。</description></item><item><title>Easysearch 布尔查询子句重排序（三）｜WAND 动态剪枝</title><link>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-3/</link><pubDate>Fri, 28 Aug 2026 10:00:00 +0800</pubDate><guid>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-3/</guid><description>Lucene 如何用 WAND 算法实现 Top-K 的动态剪枝
INFINI Easysearch 是一款专注于企业级场景的分布式近实时搜索与分析引擎。它以 Apache Lucene 为内核进行了增强，在保持与行业主流搜索协议及开发生态完全兼容的同时，重点强化了安全性、稳定性、压缩率及信创兼容性。
一、回顾与引入 # 在 第二篇中，我们深入解析了合取查询的核心优化：ConjunctionDISI 按 cost 排序，让最稀疏的迭代器领跑。这套机制的前提是 AND 语义——所有子句都必须匹配，所以&amp;quot;谁最少&amp;quot;就决定了跳转的速度。
本文聚焦析取（SHOULD）场景。关键转变在于：不需要全部匹配，而是找 Top-K 高分文档。 优化目标从&amp;quot;最少匹配&amp;quot;变为&amp;quot;最高分数贡献&amp;quot;——cost 最低的子句不一定分数最高，而分数最高的子句才最可能帮你快速找到 Top-K。
这就是 WAND 算法的用武之地。
二、为什么析取不能简单按 cost 排序？ # 合取和析取的本质差异决定了它们的优化策略必须不同：
维度 合取（MUST） 析取（SHOULD） 语义 所有子句都匹配 至少部分子句匹配 优化目标 快速排除不匹配文档 快速找到 Top-K 高分文档 排序依据 cost（谁最少谁领头） maxScore（谁分最高谁优先推进） 关键操作 跳过不匹配的文档 跳过不可能进 Top-K 的文档 为什么 cost 排序在析取中不适用？看一个析取查询 should: [quantum, the, machine_learning]，找 Top-10：</description></item><item><title>Easysearch 布尔查询子句重排序（二）｜ConjunctionDISI 按 cost 排序源码解析</title><link>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-2/</link><pubDate>Thu, 27 Aug 2026 08:00:00 +0800</pubDate><guid>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-2/</guid><description>Lucene 如何让最稀疏的迭代器领跑，最大化跳过无效文档
INFINI Easysearch 是一款专注于企业级场景的分布式近实时搜索与分析引擎。它以 Apache Lucene 为内核进行了增强，在保持与行业主流搜索协议及开发生态完全兼容的同时，重点强化了安全性、稳定性、压缩率及信创兼容性。
一、回顾与引入 # 在 第一篇中，我们走完了布尔查询从用户 JSON 到 Lucene 执行的构建层旅程：Easysearch 的 BoolQueryBuilder 会保留同类子句的书写顺序，Lucene 的 BooleanQuery.rewrite() 则通过等价改写简化查询结构。
其中，和本文关系最直接的是 SHOULD + FILTER → MUST：一个原本只是“可选加分”的 SHOULD 子句，如果同时出现在 FILTER 中，就会被改写成 MUST。它的执行路径也随之改变——从可选评分路径，进入更直接的合取路径。
所谓合取路径，就是按 AND 语义执行查询：所有必选条件都要同时满足，任意一个不满足就可以跳过该文档。对于 MUST / FILTER 这类合取子句，真正影响性能的不是用户在 JSON 里先写谁、后写谁，而是 Lucene 在执行层如何安排它们的检查顺序。
这就是本文要讲的“布尔查询子句重排序”：进入 Scorer 构造阶段后，每个 MUST / FILTER 子句会变成对应的文档迭代器，Lucene 再按 cost() 对这些迭代器重新排序，让匹配文档最少的迭代器先领跑。
一个直觉可以帮助我们理解：在 AND 查询中，谁的结果最少，谁最有&amp;quot;话语权&amp;quot;。因为 AND 语义要求所有条件都满足，所以结果最少的那个条件能最快地排除不满足的文档，剩下的条件只需要确认即可。
本文就专注于这条合取路径的核心机制：ConjunctionDISI 如何按 cost 排序，让最稀疏的迭代器领跑整场迭代。
二、前置：什么情况下走 ConjunctionScorer？ # 上面已经说明，rewrite 可能会把子句带入合取路径；但并不是所有 bool 查询都会走这条路径。本节先界定范围：哪些查询会进入合取路径，哪些不会。Lucene 在 Boolean2ScorerSupplier.</description></item><item><title>Easysearch 布尔查询子句重排序（一）｜你的 BoolQuery 写法，真的影响性能吗？</title><link>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-1/</link><pubDate>Wed, 26 Aug 2026 08:00:00 +0800</pubDate><guid>https://infinilabs.cn/blog/2026/easysearch-boolean-query-clause-reordering-part-1/</guid><description>从 Easysearch 到 Lucene，查询构建层的 11 条优化规则
INFINI Easysearch 是一款专注于企业级场景的分布式近实时搜索与分析引擎。它以 Apache Lucene 为内核进行了增强，在保持与行业主流搜索协议及开发生态完全兼容的同时，重点强化了安全性、稳定性、压缩率及信创兼容性。
一、开篇：一个常见的误解 # &amp;ldquo;must 里面，是不是应该把匹配文档少的条件写在前面？这样能提前过滤掉大量文档，性能更好？&amp;rdquo;
这个直觉来得很自然，但它是错的。
┌─────────────────────────────────────┐ │ 用户的直觉： │ │ must: [高频词, 低频词] → 慢 │ │ must: [低频词, 高频词] → 快 │ │ │ │ 实际情况： │ │ 两种写法性能完全相同！ │ │ Lucene 执行时自动按 cost 排序 │ └─────────────────────────────────────┘ Easysearch 执行时会按 cost 自动重排子句顺序，与你写查询时的顺序无关。不过&amp;quot;子句顺序不重要&amp;quot;并非处处成立，它有一条跟版本挂钩的边界——must/filter 里混入 prefix/wildcard 这类多词查询时，老版本引擎会重新对顺序敏感（详见 第二篇 §八的边界说明）。而且&amp;quot;子句顺序不重要&amp;quot;也不代表&amp;quot;怎么写都一样&amp;quot;——理解引擎自动优化的边界在哪里，才能设计出更合理的查询结构。
本文是系列第一篇，聚焦构建层：从你发出 JSON 到查询进入执行引擎，中间经历了哪些变换？哪些优化在这个阶段完成？哪些要留到执行层？后续三篇将分别深入合取查询的 cost 排序、析取查询的 WAND 剪枝，以及 Block-Max 块级剪枝与实战验证。</description></item></channel></rss>