【问题标题】:Can we use SpanNearQuery in phonetic index?我们可以在语音索引中使用 SpanNearQuery 吗?
【发布时间】:2016-07-29 14:03:12
【问题描述】:

我已经实现了一个基于 lucene 的软件来索引超过 1000 万人的名字,这些名字可以用不同的方式书写,比如“Luíz”和“Luis”。该索引是使用各个标记的语音值创建的(创建了一个自定义分析器)。

目前,我正在使用 QueryParser 查询给定名称,结果很好。但是,在“Lucene in Action”一书中提到,SpanNearQuery 可以使用令牌的接近度来改进我的查询。我已经使用 SpanNearQuery 针对名称的非语音索引,与 QueryParser 相比,结果更好。

由于我们应该使用用于索引的分析器进行查询,我找不到如何同时使用自定义语音分析器和 SpanNearQuery,或者改写:

    how can I use SpanNearQuery on the phonetic index?

提前致谢。

【问题讨论】:

    标签: lucene full-text-search


    【解决方案1】:

    我的第一个想法是:带有 slop 的短语查询不会完成这项工作吗?那肯定是最简单的方法:

    "term1 term2"~5
    

    这将使用您的语音分析器,并使用生成的标记生成邻近查询。


    所以,如果您真的需要在这里使用 SpanQueries(也许您正在使用模糊查询或通配符等,或者 PhraseQuery 一直在威胁您,而您不想再与它),您需要自己进行分析。您可以通过从Analyzer.tokenStream 获取 TokenStream 并遍历分析的令牌来完成此操作。

    如果您使用的语音算法会为每个术语生成一个代码(例如 soundex):

    SpanNearQuery.Builder nearBuilder = new SpanNearQuery.Builder("text", true);
    nearBuilder.setSlop(4);
    
    TokenStream stream = analyzer.tokenStream("text", queryStringToParse);
    stream.addAttribute(CharTermAttribute.class);
    stream.reset();
    while(stream.incrementToken()) {
        CharTermAttribute token = stream.getAttribute(CharTermAttribute.class);
        nearBuilder.addClause(new SpanTermQuery(new Term("text", token.toString())));
    }
    Query finalQuery = nearBuilder.build();
    stream.close();
    

    如果您使用双变位,您可以在同一位置有 1-2 个术语,这有点复杂,因为您需要考虑这些位置增量:

    SpanNearQuery.Builder nearBuilder = new SpanNearQuery.Builder("text", true);
    nearBuilder.setSlop(4);
    
    TokenStream stream = analyzer.tokenStream("text", "through and through");
    stream.addAttribute(CharTermAttribute.class);
    stream.addAttribute(PositionIncrementAttribute.class);
    stream.reset();
    String queuedToken = null;
    while(stream.incrementToken()) {
        CharTermAttribute token = stream.getAttribute(CharTermAttribute.class);
        PositionIncrementAttribute increment = stream.getAttribute(PositionIncrementAttribute.class);
    
        if (increment.getPositionIncrement() == 0) {
            nearBuilder.addClause(new SpanOrQuery(
                    new SpanTermQuery(new Term("text", queuedToken)),
                    new SpanTermQuery(new Term("text", token.toString()))
                    ));
            queuedToken = null;
        }
        else if (increment.getPositionIncrement() >= 1 && queuedToken != null) {
            nearBuilder.addClause(new SpanTermQuery(new Term("text", queuedToken)));
            queuedToken = token.toString();
        }
        else {
            queuedToken = token.toString();
        }
    }
    
    if (queuedToken != null) {
        nearBuilder.addClause(new SpanTermQuery(new Term("text", queuedToken)));
    }
    
    Query finalQuery = nearBuilder.build();
    stream.close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 2016-05-02
      • 1970-01-01
      • 2014-09-14
      相关资源
      最近更新 更多