1

Luceneインデックスを検索するために、検索語文字列からブールクエリを構築しています。これらの文字列を、インデックスに使用しているアナライザーである標準アナライザーで分析したいと思います。たとえば、Luceneのドキュメントでは、ハイフンによって数字は一緒にとどまるが、単語はトークン化されると記載されているため、は、、foo-bar 1-2-3として分割する必要があります。これを行うための最良の方法は何ですか?foobar1-2-3

現在、QueryParserを介して検索語文字列を実行しています。

QueryParser parser = new QueryParser("", new StandardAnalyzer()); 
Query query = parser.parse(aSearchTermString);

これに伴う問題は、引用符が挿入されることです。たとえば、は、にfoo-bar 1-2-3なります。これは、Luceneがとにトークン化されているため、何も返しません。"foo bar"1-2-3foo-barfoobar

引用符を削除してこの状況をハックしたくないのは、replaceおそらく何かが足りないか、何かが間違っていると感じているからです。

4

1 に答える 1

1

私は実際に に対して異なる結果を得ていStandardAnalyzerます。次のコードを検討してください (Lucene v4 を使用):

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);
    }
}

プリントの上:

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

StandardAnalyzerしたがって、上記のコードは、たとえば とは異なりClassicAnalyzer、必要に応じて異なるトークンに分割する必要があることを証明して1-2-3います。クエリの場合、スペースを含むすべてのキーワードをエスケープする必要があります。そうしないと、QP はこれが別の意味であると判断します。

クエリ文字列をエスケープしたくない場合は、(printTokens上記の方法のように) 手動でいつでもトークン化できます。次に、各トークンを でラップし、TermQueryすべての TermQueries を にスタックしますBooleanQuery

于 2013-01-22T22:23:59.910 に答える