java - 带有 CustomAnalyzer 的 QueryParser 弄乱了 PatternReplaceCharFilter 的使用顺序

标签 java lucene query-parser

我在 lucene 6.0.0 中使用 org.apache.lucene.queryparser.classic.QueryParser 来使用 CustomAnalyzer 解析查询,如下所示:

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 则在之后使用。有人对此有解释吗?这不是一个错误吗?

最佳答案

不,这不是错误。 CharFilters 总是在标记化之前应用,无论是在查询时间还是索引时间。

但是,空格在 QueryParser 语法中是有意义的,它完全独立于分析。空格分隔查询的子句,每个子句单独分析。如果您不依赖默认字段,这将更容易看到,在这种情况下,我们需要重写查询:avatar-film fiction,改为:name:avatar-film name :小说。 “avatar-film”和“fiction”这两个子句中的每一个都单独分析,导致您看到的结果。

尝试使用短语查询:

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

您应该会看到预期的结果。

关于java - 带有 CustomAnalyzer 的 QueryParser 弄乱了 PatternReplaceCharFilter 的使用顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36910505/

相关文章:

java - Lucene 分析器处理 yo 和 ye(俄语字符)

zend-framework - Zend Lucene

java - Lucene 解析查询 : Cannot parse '' : Encountered "<EOF>" at line 1, 第 0 列时出错

java - AWS SDK无法读取环境变量

java - 为什么当有一个尚未完成的完成阶段时主线程不终止?

autocomplete - 如何使用Lucene或类似方法为超大型数据集的类型提前构造索引?

Elasticsearch 别名有多个写入索引(不是任何其他问题的副本)

Java JTable 转到行错误

java - 使用缓冲区复制时更改了新位图