2

我已经从一组文档中用 lucene 编写了一个索引。我的文档有 2 个字段,并被添加到索引中,如下所示:

Document doc = new Document();
doc.add(new TextField("Title", "I am a title", Field.Store.NO));
doc.add(new TextField("Text", "random text content", Field.Store.NO));
indexWriter.addDocument(doc);

我想阅读索引并获取每个(术语,文档)对的术语频率。

如果我只有 1 个字段,比如说“文本”,我会使用以下代码:

IndexReader indexReader = ...;
Terms terms = MultiFields.getTerms(indexReader, "Text"); // get all terms of this field
TermsEnum termsIterator = terms.iterator();
BytesRef term;
// For every term in the "Text" Field:
while ((term = termsIterator.next()) != null) {
    String termString = term.utf8ToString(); // The term
    PostingsEnum postingsEnum = MultiFields.getTermDocsEnum(indexReader,
        "Text", term, PostingsEnum.FREQS);
    int i;
    // For every doc which contains the current term in the "Text" field:
    while ((i = postingsEnum.nextDoc()) != PostingsEnum.NO_MORE_DOCS) {
        Document doc = indexReader.document(i); // The document
        int freq = postingsEnum.freq(); // Frequency of term in doc
    }
}

但是,由于我有 2 个字段(“标题”和“文本”),为了获得(术语,文档)对的总术语频率,我首先需要get every (term, doc) pair frequency for the "Title" field将它们保存在内存中,然后get every (term, doc) pair frequency for the "Text" field手动组合它们对于返回的每个唯一 (term, doc) 对。

因此,此方法很可能会多次迭代 (term, doc) 对,因为相同的 (term, doc) 对可能同时存在于 Title”和“Text”字段中(如果文档具有相同的术语在他的“标题”和“文本”中)。

Lucene API 有什么方法可以遍历所有组合的字段吗?(避免多次重复相同的对)

4

1 回答 1

1

您有两个字段,您需要每个文档的所有标记的频率作为每个字段和文档的频率之和。

请记住,BytesRef(和 Integer)实现了 Comparable-interface:您的令牌流(TermsEnum)和每个相关的文档流(PostingEnum)是有序的。

所以你有两次合并两个有序流。您不必在内存中保存超过每个流的头部。

于 2015-12-28T18:10:00.063 回答