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

将Lucene从3.5升级到4.10-如何处理JavaAPI更改,java,lucene,Java,Lucene,我目前正在将一个搜索引擎应用程序从Lucene 3.5.0升级到4.10.3版。在版本4中有一些实质性的API更改破坏了向后兼容性。我已经设法解决了大部分问题,但仍有一些问题需要我的帮助: “无法从分析器重写最终方法” 原始代码扩展了Analyzer类和overrode tokenStream(…) 但这种方法现在是最终的,我不知道如何理解更改日志中的以下注释: ReusableAnalyzerBase已重命名为Analyzer。所有Analyzer实现现在都必须使用Analyzer.Token

我目前正在将一个搜索引擎应用程序从Lucene 3.5.0升级到4.10.3版。在版本4中有一些实质性的API更改破坏了向后兼容性。我已经设法解决了大部分问题,但仍有一些问题需要我的帮助:

  • “无法从分析器重写最终方法”
  • 原始代码扩展了Analyzer类和overrode tokenStream(…)

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

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

    上述方法还有一个问题:

  • “类型CharReader的方法get(Reader)未定义”
  • 这里似乎也发生了一些相当大的变化

  • “TermPositionVector无法解析为类型”
  • 这门课现在已经在Lucene 4上了。有没有简单的修复方法?从更改日志:

    术语向量API(TermFreqVector、TermPositionVector、TermVectorMapper)已被删除,以支持上述灵活的索引API,从术语向量中呈现文档的单个文档反向索引

    可能与此有关:

  • 类型IndexReader的方法getTermFreqVector(int,String)未定义
  • 这两个问题都发生在这里,例如:

    TermPositionVector termVector = (TermPositionVector) reader.getTermFreqVector(...);
    
    (“reader”是IndexReader类型)

    如果您能在这些问题上提供帮助,我将不胜感激。

    我在Lucene邮件列表中找到了core developer对您问题的解答。我花了一些时间来熟悉新的API,所以我需要在忘记之前写下一些东西

    这些注释适用于Lucene 4.10.3

    实现分析器(1-2)
    newanalyzer(){
    @凌驾
    受保护的TokenStreamComponents createComponents(字符串字段名、读卡器){
    标记器源=新的WhitespaceTokenizer(新的HTMLStripCharFilter(读卡器));
    令牌流接收器=新的小写筛选器(源);
    返回新组件(源、接收器);
    }
    };
    
  • 的构造函数接受一个源和一个接收器。接收器是您的令牌流的最终结果,由
    Analyzer.tokenStream()
    返回,因此将其设置为您的筛选器链。源是应用任何筛选器之前的令牌流
  • ,尽管名称不同,实际上是java.io.Reader的一个子类,它删除了HTML结构,因此您不再需要CharReader
  • 术语向量替换(3-4) 术语向量在Lucene 4中的工作方式不同,因此没有直接的方法交换。具体答案取决于您的需求

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

    Document doc=新文档();
    FieldType f=新的FieldType();
    f、 设置索引(true);
    f、 设置存储项向量(真);
    f、 设置存储矢量位置(真);
    添加文档(新字段(“文本”、“您好”,f));
    
    最后,为了获得文档字段的频率和位置信息,您可以像下面这样深入研究新的API(改编自):

    //IndexReader-ir;
    //int-docID=0;
    Terms=ir.getTermVector(docID,“text”);
    terms.hasPositions();//如果将字段设置为存储位置,则应为true
    TermsEnum TermsEnum=terms.iterator(null);
    BytesRef term=null;
    //探索这个领域的术语
    while((term=termsEnum.next())!=null){
    //通过文档枚举,在本例中仅枚举一个
    DocsAndPositionsEnum docsEnum=termsEnum.docsAndPositions(null,null);
    int docIdEnum;
    而((docIdEnum=docsEnum.nextDoc())!=docidSetInterator.NO\u MORE\u DOCS){
    对于(int i=0;i

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

    试试Lucene邮件列表。我觉得Lucene人对这种事情太自由了。
    TermPositionVector termVector = (TermPositionVector) reader.getTermFreqVector(...);
    
    // 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());
            }
        }
    }