2016-07-29 3 views
2

저는 1 천만 명이 넘는 사람의 이름을 색인하기 위해 lucene 기반 소프트웨어를 구현했습니다.이 이름은 "Luíz"및 "Luis"와 같은 다른 방법으로 작성할 수 있습니다. 색인은 각 토큰의 음운 값을 사용하여 작성되었습니다 (사용자 정의 분석기가 작성되었습니다).SpanNearQuery를 소리 나는 색인으로 사용할 수 있습니까?

현재 QueryParser를 사용하여 주어진 이름을 쿼리하여 좋은 결과를 얻습니다. 그러나 "Lucene in Action"이라는 책에서 SpanNearQuery는 토큰의 근접성을 사용하여 쿼리를 향상시킬 수 있다고 언급합니다. 필자는 SpanNearQuery와 비 음성 표제를 비교해 본 결과, QueryParser와 비교하여 우수한 결과를 보였습니다. 우리는 색인에 사용되는 것과 동일한 분석기를 사용하여 쿼리해야으로

, 나는 같은 시간에 내 사용자 정의 음성 분석기와 SpanNearQuery을 사용하는 방법을 찾거나 문구를 수정하지 못했습니다 : 사전에

how can I use SpanNearQuery on the phonetic index? 

감사합니다.

답변

1

내 생각은 다음과 같습니다. slop을 사용한 문구 쿼리가 작업을 수행하지 않았습니까? 그러면 확실하게 가장 쉬운 방법이 될 것입니다.

"term1 term2"~5 

이렇게하면 음성 분석기가 사용되며 결과 토큰을 사용하여 근접 식 쿼리를 생성합니다. 당신이 정말로 여기 SpanQueries를 사용하는 필요성을 경우


그래서, (아마 당신은 퍼지 쿼리 나 와일드 카드 또는 일부 등을 사용하고, 또는 PhraseQuery는 당신을 협박 추파되었으며 더 많은 일과 아무 상관 없습니다 싶어), 직접 분석해야합니다. Analyzer.tokenStream에서 TokenStream을 가져 와서 분석 된 토큰을 반복하여이 작업을 수행 할 수 있습니다.

(예를 들어, 사운 덱스) 기간 당 하나의 코드를 생성하는 음성 알고리즘을 사용하는 경우

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(); 
관련 문제