【lucene】SpanNotQuery 存在的意义
SpanNotQuery 存在的意义就是:
在“词的位置”这一更细粒度上做布尔运算,而不仅仅在“文档”级别做 AND/OR/NOT。
它让 Lucene 从“文档检索”升级到“短语/区间检索”,满足更复杂的业务需求。 啥意思?
把它拆成三层,你就明白了:
1. 传统 BooleanQuery(文档级)
只能告诉你:
“这篇文档里同时有 apple 和 pie。”
至于这两个词在文档里相距多远、谁先谁后,它完全不知道。
举例:
- 文档 A:“I like apple and pie.” → 命中
- 文档 B:“apple …(隔 500 词)… pie.” → 也命中
你无法区分 A、B 的差异。
2. SpanQuery(区间级)
把“文档”再往下拆成“词的位置区间”,于是可以问:
“在这篇文档里,apple 和 pie 挨得不超过 3 个词。”
这就是 SpanNearQuery。
此时:
- 文档 A 会给出一段区间 `[apple, pie]`;
- 文档 B 因为距离太远,没有任何区间满足,文档就不被命中。
3. SpanNotQuery(区间级布尔运算)
在区间上再做“减法”:
“先把 所有出现 apple 的区间 拿出来,但如果这段 apple 被 ‘apple … pie 且距离≤3’ 的区间罩住,就整段扔掉。”
结果:
- 文档 A 的 apple 被“剪掉”,于是这篇文档不会被返回;
- 文档 C:“I like apple cake.” 里的 apple 没被罩住,就被保留,文档返回。
一句话类比
- BooleanQuery 像“整本书”级别的标签:这本书贴了“apple”和“pie”两张标签。
- SpanQuery 像“页码”级别的标签:第 12 页第 3 行到第 5 行是 “apple pie”。
- SpanNotQuery 像用剪刀把某几页里不想保留的段落裁掉,只把剩余段落还给读者。
因此,“升级”指的是:
从 “整本书要不要” → “把书里具体几行裁掉或保留”,粒度细得多,能满足“邻近/排除/精准高亮”等更复杂的搜索需求。