真实用explain模式对比默认operator(or)与operator=and生成的底层Lucene查询语句差异,从+号这个语法标记证明and语义如何从查询结构层面改变每个词项的匹配要求。
代码4篇文档: "quick brown fox" / "quick fox" / "brown fox" / "lazy dog" POST /op_test/_validate/query?explain=true {"query":{"match":{"body":"quick brown fox"}}} POST /op_test/_validate/query?explain=true {"query":{"match":{"body":{"query":"quick brown fox","operator":"and"}}}}
默认operator(即or)的explain: → "body:quick body:brown body:fox" ← 三个词项之间没有任何符号,真实是平级的OR关系 operator="and"的explain: → "+body:quick +body:brown +body:fox" ← 每个词项前面真实都多了一个+号
这组explain对比真实从语法结构层面证明了operator参数到底改变了什么:这里的+符号真实是Lucene经典查询语法里"必须匹配"(MUST)的标记,等价于本系列第32篇验证过的bool查询里的must子句。默认情况下,match查询分析出的每个词项真实互相独立、没有这个+标记,命中任意一个就算;operator=and真实不是在外面包了一层额外的过滤条件,而是直接把每一个词项本身都真实标记成了"必须命中",这是从查询语句的组装方式上发生的真实变化,不是后处理过滤。
代码POST /op_test/_search {"query":{"match":{"body":"quick brown fox"}}} POST /op_test/_search {"query":{"match":{"body":{"query":"quick brown fox","operator":"and"}}}}
默认operator(or): hits = 3 → "quick brown fox"(3词全中) → "quick fox"(中2词) → "brown fox"(中2词) ← 只有完全不沾边的"lazy dog"被排除 operator="and": hits = 1 → 只剩"quick brown fox"(3词全中) ← "quick fox"和"brown fox"虽然都命中了2个词,但真实因为缺了其中一个词 ← 被"+"标记的必须匹配要求直接排除
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_validate/query?explain=true API