首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Standard Analyzer清理Lucene搜索项

使用Standard Analyzer清理Lucene搜索项
EN

Stack Overflow用户
提问于 2013-01-23 01:35:00
回答 1查看 980关注 0票数 1

我们正在从搜索项字符串中构建一个布尔查询来搜索Lucene索引。我希望使用Standard Analyzer对这些字符串进行分析,这是我们用于索引的分析器。例如,foo-bar 1-2-3应该被分解为foobar1-2-3,因为Lucene文档指出连字符导致数字保持在一起,但单词被标记化。做这件事最好的方法是什么?

目前,我正在通过QueryParser运行我的搜索词字符串。

代码语言:javascript
运行
复制
QueryParser parser = new QueryParser("", new StandardAnalyzer()); 
Query query = parser.parse(aSearchTermString);

这样做的问题是插入了引号。例如,foo-bar 1-2-3变成了"foo bar"1-2-3,它不会返回任何东西,因为foo-bar 1-2-3会将foo-bar标记为foobar

我绝对不想通过删除replace的引号来解决这种情况,因为我觉得我可能遗漏了什么或做错了什么。

EN

回答 1

Stack Overflow用户

发布于 2013-01-23 06:24:00

实际上,我为StandardAnalyzer得到了不同的结果。考虑下面的代码(使用Lucene v4):

代码语言:javascript
运行
复制
public class Tokens {

    private static void printTokens(String string, Analyzer analyzer) throws IOException {
        System.out.println("Using " + analyzer.getClass().getName());
        TokenStream ts = analyzer.tokenStream("default", new StringReader(string));
        OffsetAttribute offsetAttribute = ts.addAttribute(OffsetAttribute.class);
        CharTermAttribute charTermAttribute = ts.addAttribute(CharTermAttribute.class);

        while(ts.incrementToken()) {
            int startOffset = offsetAttribute.startOffset();
            int endOffset = offsetAttribute.endOffset();
            String term = charTermAttribute.toString();
            System.out.println(term + " (" + startOffset + " " + endOffset + ")");
        }
        System.out.println();
    }

    public static void main(String[] args) throws IOException {
        printTokens("foo-bar 1-2-3", new StandardAnalyzer(Version.LUCENE_40));
        printTokens("foo-bar 1-2-3", new ClassicAnalyzer(Version.LUCENE_40));

        QueryParser standardQP = new QueryParser(Version.LUCENE_40, "", new StandardAnalyzer(Version.LUCENE_40));
        BooleanQuery q1 = (BooleanQuery) standardQP.parse("someField:(foo\\-bar\\ 1\\-2\\-3)");
        System.out.println(q1.toString() + "     # of clauses:" + q1.getClauses().length);
    }
}

上面的照片:

代码语言:javascript
运行
复制
Using org.apache.lucene.analysis.standard.StandardAnalyzer
foo (0 3)
bar (4 7)
1 (8 9)
2 (10 11)
3 (12 13)

Using org.apache.lucene.analysis.standard.ClassicAnalyzer
foo (0 3)
bar (4 7)
1-2-3 (8 13)

someField:foo someField:bar someField:1 someField:2 someField:3     # of clauses:5

因此,上面的代码证明了与ClassicAnalyzer不同的是,StandardAnalyzer应该将1-2-3拆分成不同的令牌--完全按照您的需要。对于查询,你需要转义每个关键字,包括空格,否则QP会认为这有不同的含义。

如果不想转义查询字符串,可以始终手动对其进行标记化(就像上面的printTokens方法一样),然后用TermQuery包装每个标记,并将所有TermQueries堆叠到一个BooleanQuery中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14464638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档