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

TwoPhaseIterator 两阶段验证

下面给出 可直接拷贝运行 的 Lucene 8.5.0 示例,演示 TwoPhaseIterator 两阶段验证 的完整流程。

 

场景:使用 `PhraseQuery`(短语查询),它天然携带 `TwoPhaseIterator`,第一阶段通过倒排表拿到“候选文档”,第二阶段验证 词间距与顺序。

 

---

 

1. 依赖(Maven)

 

```xml

<dependencies>

  <dependency>

    <groupId>org.apache.lucene</groupId>

    <artifactId>lucene-core</artifactId>

    <version>8.5.0</version>

  </dependency>

  <dependency>

    <groupId>org.apache.lucene</groupId>

    <artifactId>lucene-analyzers-common</artifactId>

    <version>8.5.0</version>

  </dependency>

</dependencies>

```

 

---

 

2. 完整代码

 

```java

package demo;

 

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.TextField;

import org.apache.lucene.index.*;

import org.apache.lucene.search.*;

import org.apache.lucene.store.ByteBuffersDirectory;

import org.apache.lucene.util.Bits;

 

public class TwoPhaseDemo {

    public static void main(String[] args) throws Exception {

        // 1. 建立索引

        ByteBuffersDirectory dir = new ByteBuffersDirectory();

        IndexWriterConfig cfg = new IndexWriterConfig(new StandardAnalyzer());

        IndexWriter w = new IndexWriter(dir, cfg);

 

        // 文档 1:短语完全匹配

        Document doc1 = new Document();

        doc1.add(new TextField("body", "lucene is a powerful search engine", Field.Store.YES));

        w.addDocument(doc1);

 

        // 文档 2:包含单词但顺序颠倒,短语不匹配

        Document doc2 = new Document();

        doc2.add(new TextField("body", "search lucene engine is powerful", Field.Store.YES));

        w.addDocument(doc2);

 

        w.commit();

        w.close();

 

        // 2. 打开读取器

        IndexReader reader = DirectoryReader.open(dir);

        IndexSearcher searcher = new IndexSearcher(reader);

 

        // 3. 构建 PhraseQuery(短语查询)

        PhraseQuery query = new PhraseQuery.Builder()

                .add(new Term("body", "lucene"))

                .add(new Term("body", "search"))

                .setSlop(1) // 允许 1 个词间距

                .build();

 

        // 4. 获取 Weight 与 Scorer

        Weight weight = searcher.createWeight(query, ScoreMode.COMPLETE, 1.0f);

        LeafReaderContext ctx = reader.leaves().get(0);

        Scorer scorer = weight.scorer(ctx);

 

        // 5. 两阶段遍历

        if (scorer == null) {

            System.out.println("无匹配文档");

            return;

        }

 

        TwoPhaseIterator twoPhase = scorer.twoPhaseIterator();

        if (twoPhase != null) {

            DocIdSetIterator approx = twoPhase.approximation();

            int doc;

            while ((doc = approx.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {

                // 第一阶段:倒排表快速筛选候选

                System.out.println("候选文档 doc=" + doc);

 

                // 第二阶段:精确验证短语是否满足

                if (twoPhase.matches()) {

                    Document d = searcher.doc(doc);

                    System.out.println("✅ 通过二次验证 -> " + d.get("body"));

                } else {

                    System.out.println("❌ 未通过二次验证");

                }

            }

        }

 

        reader.close();

        dir.close();

    }

}

```

 

---

 

3. 运行结果(示例)

 

```

候选文档 doc=0

✅ 通过二次验证 -> lucene is a powerful search engine

候选文档 doc=1

❌ 未通过二次验证

```

 

---

 

4. 关键点

 

- 第一阶段:`approximation().nextDoc()` 只检查两词是否都出现过(倒排表)。  

- 第二阶段:`twoPhase.matches()` 才检查 顺序 + 间距 是否满足短语规则。  

- TwoPhaseIterator 正是 Lucene 实现“先粗筛后精筛”的核心机制。

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

相关文章:

  • Fastdds中的端口号计算
  • 基于 XGBoost 与 SHAP 的医疗自动化办公与可视化系统(下)
  • 在React中,函数式组件和类组件各有优缺点
  • 射频信号(大宽高比)时频图目标检测anchors配置(下)
  • 分布式任务调度实战:XXL-JOB与Elastic-Job深度解析
  • ZKmall开源商城微服务架构实战:Java 商城系统的模块化拆分与通信之道
  • 【音视频学习】五、深入解析视频技术中的像素格式:颜色空间、位深度、存储布局
  • TR-FRET(时间分辨荧光能量共振转移)在药物研发中的热门应用简介
  • 【解决vmware ubuntu不小心删boot分区,进不去系统】
  • 在 Ubuntu 上将 Docker 降级到版本 25.0.5 (二) 降低版本,涉及兼容性问题
  • 在离线 Ubuntu 22.04机器上运行 ddkj_portainer-cn 镜像 其他相关操作也可以复刻 docker
  • centos 配置docker
  • java通过com进行pdf转换docx丢失
  • mongodb的备份和还原(精简)
  • LeetCode11~20题解
  • Visual Studio中部署PaddleOCRv5 (借助ncnn框架)
  • 如何Visual Studio 的配置从 Qt-Debug 切换到 x64-Debug
  • ESP32的ADF详解:5. Streams的API
  • 聊聊 Flutter 在 iOS 真机 Debug 运行出现 Timed out *** to update 的问题
  • GEMINUS 和 Move to Understand a 3D Scene
  • Redis的key过期策略
  • 4.3 激活函数的目的
  • LLM 幻觉一般是由于什么产生的,在模型什么部位产生
  • 计算机组成原理——数据的表示和运算2
  • 手机开启16k Page Size
  • J2EE模式---服务定位器模式
  • JavaEE Spring框架的概述与对比无框架下的优势
  • 关于原车一键启动升级手机控车的核心信息及注意事项
  • 第五章第一节 EXTI 外部中断
  • Adobe全系列下载 官方原版补丁