Lucene 8.5.1 中 IndexReader.getTermVector(int docID ,String field) 中的 docID 是啥,它是如何工作的?

Posted

技术标签:

【中文标题】Lucene 8.5.1 中 IndexReader.getTermVector(int docID ,String field) 中的 docID 是啥,它是如何工作的?【英文标题】:What is docID in IndexReader.getTermVector(int docID ,String field) in Lucene 8.5.1 and how does it work?Lucene 8.5.1 中 IndexReader.getTermVector(int docID ,String field) 中的 docID 是什么,它是如何工作的? 【发布时间】:2020-10-07 21:30:51 【问题描述】:

我正在尝试从 Lucene 的文档字段中获取所有名为 Terms 的术语和相关帖子(即如何计算 Lucene 中的术语频率?)。根据documentation,有一种方法可以做到这一点:

public final Terms getTermVector​(int docID, String field) throws IOException

检索此文档和字段的词向量,如果词向量没有被索引,则返回 null。返回的 Fields 实例就像一个单文档倒排索引(docID 将为 0)。

有一个名为int docID 的字段。这是什么??对于给定的文档,它的 id 字段是什么,Lucene 如何识别它? 根据 Lucene 的文档,我使用 StringField 作为 id,它不是 int

import org.apache.lucene.document.*;
Document doc = new Document();
Field idField = new StringField("id",post.Id,Field.Store.YES);
Field bodyField = new TextField("body", post.Body, Field.Store.YES);
doc.add(idField);
doc.add(bodyField);

我有五个问题:

    Lucene 如何识别id 字段用作此文档的docId?甚至 Lucene 是否这样做?? 我使用String 作为id,但是这个方法给出了int。它会导致问题吗? 有没有合适的方法来获取帖子? 我用过TextField。有没有办法检索该字段的术语向量(Terms)?我不想按照 here 的说明重新索引我的文档,因为它太大 (35-GB)。 有没有什么方法可以从TextField获取术语计数和每个术语频率?

【问题讨论】:

【参考方案1】:

要计算词频,我们可以使用IndexReader.getTermVector(int docID ,String field)int docID 是一个引用 Lucene 创建的文档 ID 的字段。您可以通过以下代码检索docID

String index = "index/AIndex/";
String query = "the query text"

IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
IndexSearcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();

QueryParser parser = new QueryParser("docField", analyzer);
Query lQuery = parser.parse(query);

]TopDocs results = searcher.search(lQuery ,  requiredHits);
ScoreDoc[] hits = results.scoreDocs;
int numTotalHits = (int) results.totalHits.value;

for (int i = start; i < numTotalHits; i++)
 
   int docID = hits[i].doc;
   Terms termVector = reader.getTermVector(docID, "docField");
 

每个termVector 对象都有与文档字段相关的术语和频率,您可以通过以下代码检索:

private HashMap<String,Long> termsFrequency = new HashMap<>();
TermsEnum itr = termVector.iterator();
int allTermFrequency=0;
BytesRef term;

while ((term = itr.next()) != null)
  String termText = term.utf8ToString();
  long tf = itr.totalTermFreq();
  termsFrequency.put(termText, tf);
  allTermFrequency += itr.totalTermFreq();

注意:当您为文档编制索引时,不要忘记设置存储术语向量,正如我所解释的 here(或 this one)。如果您在未设置存储术语向量的情况下为文档编制索引,则方法 getTermVector 将返回 null。默认情况下,所有类型的预定义 Lucene Field 禁用此选项。所以你需要设置它。

【讨论】:

以上是关于Lucene 8.5.1 中 IndexReader.getTermVector(int docID ,String field) 中的 docID 是啥,它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

不在lucene中查询

lucene中分词和索引的区别

Lucene学习总结之二:Lucene的总体架构

Lucene学习总结之二:Lucene的总体架构

Lucene全文搜索原理与使用

实战 Lucene,第 1 部分: 初识 Lucene (zhuan)