繁体   English   中英

将Lucene从3.5升级到4.10 - 如何处理Java API更改

[英]Upgrading Lucene from 3.5 to 4.10 - how to handle Java API changes

我目前正在将搜索引擎应用程序从Lucene 3.5.0升级到版本4.10.3。 版本4中有一些实质性的API更改会破坏向后兼容性。 我已经成功解决了大部分问题,但仍然存在一些问题,我可以使用以下方面的帮助:

  1. “无法覆盖Analyzer的最终方法”

原始代码扩展了Analyzer类和overrode tokenStream(...)。

@Override
public TokenStream tokenStream(String fieldName, Reader reader) {
    CharStream charStream = CharReader.get(reader);        
    return
        new LowerCaseFilter(version,
            new SeparationFilter(version,
                new WhitespaceTokenizer(version,
                    new HTMLStripFilter(charStream))));
}

但是这种方法现在是最终的,我不知道如何理解更改日志中的以下注释:

ReusableAnalyzerBase已重命名为Analyzer。 所有Analyzer实现现在必须使用Analyzer.TokenStreamComponents,而不是重写.tokenStream()和.reusableTokenStream()(现在是最终的)。

上面引用的方法还有另一个问题:

  1. “对于CharReader类型,方法get(Reader)未定义”

这里似乎也有一些相当大的变化。

  1. “TermPositionVector无法解析为类型”

这个课程现在在Lucene 4中消失了。对此有什么简单的修复方法吗? 从更改日志中:

已删除术语向量API(TermFreqVector,TermPositionVector,TermVectorMapper)以支持上述灵活的索引API,从术语向量呈现文档的单文档倒排索引。

可能与此相关:

  1. “类型为IndexReader的方法getTermFreqVector(int,String)未定义。”

这两个问题都出现在这里,例如:

TermPositionVector termVector = (TermPositionVector) reader.getTermFreqVector(...);

(“读者”是TypeReader类型)

我很感激这些问题的任何帮助。

我找到了核心开发人员Uwe Schindler对Lucene邮件列表中的问题的回复 我花了一些时间来探索新的API,所以我需要在忘记之前写下一些东西。

这些说明适用于Lucene 4.10.3。

实施分析仪(1-2)

new Analyzer() {
    @Override
    protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
        Tokenizer source = new WhitespaceTokenizer(new HTMLStripCharFilter(reader));
        TokenStream sink = new LowerCaseFilter(source);
        return new TokenStreamComponents(source, sink);
    }
};
  1. TokenStreamComponents的构造函数采用源和接收器。 接收器是您的令牌流的最终结果,由Analyzer.tokenStream()返回,因此将其设置为您的过滤器链。 在应用任何过滤器之前,源是令牌流。
  2. HTMLStripCharFilter ,尽管它的名字,实际上是java.io.Reader的子类,它删除了HTML结构,所以你不再需要CharReader。

术语向量替换(3-4)

术语向量在Lucene 4中的工作方式不同,因此没有直接的方法交换。 具体答案取决于您的要求。

如果您需要位置信息,则必须首先使用位置信息索引字段:

Document doc = new Document();
FieldType f = new FieldType();
f.setIndexed(true);
f.setStoreTermVectors(true);
f.setStoreTermVectorPositions(true);
doc.add(new Field("text", "hello", f));

最后,为了获得文档字段的频率和位置信息,您可以深入了解这样的新API(根据此答案改编):

// IndexReader ir;
// int docID = 0;
Terms terms = ir.getTermVector(docID, "text");
terms.hasPositions(); // should be true if you set the field to store positions
TermsEnum termsEnum = terms.iterator(null);
BytesRef term = null;
// Explore the terms for this field
while ((term = termsEnum.next()) != null) {
    // Enumerate through documents, in this case only one
    DocsAndPositionsEnum docsEnum = termsEnum.docsAndPositions(null, null);
    int docIdEnum;
    while ((docIdEnum = docsEnum.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
        for (int i = 0; i < docsEnum.freq(); i++) {
            System.out.println(term.utf8ToString() + " " + docIdEnum + " "
                    + docsEnum.nextPosition());
        }
    }
}

如果Terms.iterator()返回实际的Iterable,那就Terms.iterator()了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM