Java Lucene查询解析器使用过滤器进行通配符查询

Java Lucene查询解析器使用过滤器进行通配符查询,java,lucene,Java,Lucene,我的问题是如何使用Lucene解析通配符查询,即查询项通过令牌过滤器传递 我正在使用一个定制的分析器和几个文件管理器(例如ASCIIFoldingFilter,但这只是一个示例)。我的问题是,每当Lucene的QueryParser检测到其中一个子查询是WildcardQuery,它就设计而言[1]忽略了分析器 这意味着对über的查询已正确过滤 über -> uber 但对über*(带有通配符)的查询根本不会通过过滤器传递: über* -> über* 显然,这意味着——

我的问题是如何使用Lucene解析通配符查询,即查询项通过
令牌过滤器传递

我正在使用一个定制的
分析器
和几个文件管理器(例如
ASCIIFoldingFilter
,但这只是一个示例)。我的问题是,每当Lucene的
QueryParser
检测到其中一个子查询是
WildcardQuery
,它就设计而言[1]忽略了
分析器

这意味着对über的查询已正确过滤

über -> uber
但对über*(带有通配符)的查询根本不会通过过滤器传递:

über* -> über*
显然,这意味着——当索引端所有标记都被过滤时——任何包含的查询都不能有匹配项

问:我如何强制Lucene也过滤通配符查询?我正在寻找一种至少能稍微重复使用Lucene代码库的方法;-)

注意:作为一个输入,我收到一个查询字符串,因此以编程方式构建查询不是一个选项。 注意:我使用的是Lucene 4.5.1

[1]

背景:

// analyzer applies filters in Analyzer#createComponents (String, Reader)
Analyzer analyzer = new CustomAnalyzer (Version.LUCENE_45); 

// I'm using org.apache.lucene.queryparser.classic.MultiFieldQueryParser
QueryParser parser = new MultiFieldQueryParser (Version.LUCENE_45, fields, analyzer);
parser.setAllowLeadingWildcard (true);
parser.setMultiTermRewriteMethod (MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);

// actual parsing of the input query
Query query = parser.parse (input);

好的,我找到了一个解决方案:我正在扩展
QueryParser
以覆盖
#getWildcardQuery(String,String)
。通过这种方式,我可以在检测到通配符查询后和创建通配符查询前截取并更改术语:

@Override
protected Query getWildcardQuery (String field, String termStr) throws ParseException
{
    String term = termStr;
    TokenStream stream = null;
    try
    {
        // we want only a single token and we don't want to lose special characters
        stream = new KeywordTokenizer (new StringReader (term));

        stream = new LowerCaseFilter (Version.LUCENE_45, stream);
        stream = new ASCIIFoldingFilter (stream);

        CharTermAttribute charTermAttribute = stream.addAttribute (CharTermAttribute.class);

        stream.reset ();
        while (stream.incrementToken ())
        {
            term = charTermAttribute.toString ();
        }
    }
    catch (IOException e)
    {
        LOGGER.debug ("Failed to filter search query token {}", term, e);
    }
    finally
    {
        IOUtils.closeQuietly (stream);
    }
    return super.getWildcardQuery (field, term);
}
此解决方案基于类似的问题:

注意:在我的代码中,将所有过滤器保留在单个位置实际上有点复杂


不过,我仍然觉得应该有更好的解决方案。

我不明白analyzer如何处理您的查询。它会如何影响它?