2016-04-28 3 views
2

Я использую org.apache.lucene.queryparser.classic.QueryParser в Lucene 6.0.0 для разбора запросов с использованием CustomAnalyzer, как показано ниже:QueryParser с CustomAnalyzer портит порядок использования PatternReplaceCharFilter

public static void testFilmAnalyzer() throws IOException, ParseException { 
    CustomAnalyzer nameAnalyzer = CustomAnalyzer.builder() 
      .addCharFilter("patternreplace", 
        "pattern", "(movie|film|picture).*", 
        "replacement", "") 
      .withTokenizer("standard") 
      .build(); 

    QueryParser qp = new QueryParser("name", nameAnalyzer); 
    qp.setDefaultOperator(QueryParser.Operator.AND); 
    String[] strs = {"avatar film fiction", "avatar-film fiction", "avatar-film-fiction"}; 

    for (String str : strs) { 
     System.out.println("Analyzing \"" + str + "\":"); 
     showTokens(str, nameAnalyzer); 
     Query q = qp.parse(str); 
     System.out.println("Parsed query of \"" + str + "\":"); 
     System.out.println(q + "\n"); 
    } 
} 

private static void showTokens(String text, Analyzer analyzer) throws IOException { 
    StringReader reader = new StringReader(text); 
    TokenStream stream = analyzer.tokenStream("name", reader); 
    CharTermAttribute term = stream.addAttribute(CharTermAttribute.class); 
    stream.reset(); 
    while (stream.incrementToken()) { 
     System.out.print("[" + term.toString() + "]"); 
    } 
    stream.close(); 
    System.out.println(); 
} 

я получаю следующие выходные, когда я призываю testFilmAnalyzer:

Analyzing "avatar film fiction": 
[avatar] 
Parsed query of "avatar film fiction": 
+name:avatar +name:fiction 

Analyzing "avatar-film fiction": 
[avatar] 
Parsed query of "avatar-film fiction": 
+name:avatar +name:fiction 

Analyzing "avatar-film-fiction": 
[avatar] 
Parsed query of "avatar-film-fiction": 
name:avatar 

Похоже, анализатор использует PatternReplaceCharFilter в его правильном предполагаемом порядке (т.е. до лексемизации), в то время как QueryParser делает это потом. У кого-нибудь есть объяснение? Разве это не ошибка?

ответ

1

Нет, это не ошибка. CharFilters - это всегда, применяемый до токенизации, будь то во время запроса или время индекса.

Однако, пробелы имеют смысл в синтаксисе QueryParser, который полностью не зависит от анализа. Разделяет отдельные предложения запроса, и каждое предложение анализируется на своем собственном. Это проще увидеть, если вы не полагаетесь на поле по умолчанию, и в этом случае нам нужно будет переписать запрос: avatar-film fiction, to: name:avatar-film name:fiction. Каждый из двух статей, «аватар-фильм» и «фикция», анализируется отдельно, вызывая результаты, которые вы видите.

Try используя фразы запросы:

String[] strs = {"\"avatar film fiction\"", "\"avatar-film fiction\"", "\"avatar-film-fiction\""}; 

и вы увидите результаты, которые вы ожидали.

Смежные вопросы