如何从Lucene的特定字段中获取唯一术语列表?

Hos*_*ein 9 java lucene

我有一个包含多个字段的大型语料库的索引.这些字段中只有一个包含文本.我需要根据这个字段从整个索引中提取唯一的单词.有谁知道我如何用java中的Lucene做到这一点?

pok*_*110 28

如果您使用的是Lucene 4.0 api,则需要从索引阅读器中获取字段.然后,Fields提供了获取索引中每个字段的术语的方法.以下是如何执行此操作的示例:

        Fields fields = MultiFields.getFields(indexReader);
        Terms terms = fields.terms("field");
        TermsEnum iterator = terms.iterator(null);
        BytesRef byteRef = null;
        while((byteRef = iterator.next()) != null) {
            String term = new String(byteRef.bytes, byteRef.offset, byteRef.length);

        }
Run Code Online (Sandbox Code Playgroud)

最后,对于新版本的Lucene,您可以从BytesRef调用中获取字符串:

       byteRef.utf8ToString();
Run Code Online (Sandbox Code Playgroud)

代替

       new String(byteRef.bytes, byteRef.offset, byteRef.length);
Run Code Online (Sandbox Code Playgroud)

如果要获取文档频率,可以执行以下操作:

       int docFreq = iterator.docFreq();
Run Code Online (Sandbox Code Playgroud)


mil*_*lan 9

您正在寻找术语向量(字段中所有单词的集合以及每个单词的使用次数,不包括停用单词).您将为索引中的每个文档使用IndexReader的getTermFreqVector(docid,field),并HashSet使用它们填充a .

另一种方法是使用terms()并仅选择您感兴趣的字段的术语:

IndexReader reader = IndexReader.open(index);
TermEnum terms = reader.terms();
Set<String> uniqueTerms = new HashSet<String>();
while (terms.next()) {
        final Term term = terms.term();
        if (term.field().equals("field_name")) {
                uniqueTerms.add(term.text());
        }
}
Run Code Online (Sandbox Code Playgroud)

这不是最佳解决方案,您正在阅读然后丢弃所有其他字段.FieldsLucene 4中有一个类,只返回单个字段的术语(字段).

  • 即使在Lucene 3上,您也不必为此扫描所有字段的条款.这似乎没有记录,但`reader.terms(new Term(fieldName,termText))`将返回按字段名称排序的`Term`-s,以及按术语文本排序的相同字段中的术语.因此,如果你在`!term.field().equals(fieldName)`的第一次使用`terms.term(fieldName,"")`和`break`,你就得到了你想要的.但由于这是无证的,有一天会不会破裂?据我所知,Lucene自己的`WildcardQuery`也是如此,而且Lucene 3不太可能再发生变化. (2认同)