簡體   English   中英

使用標准分析儀擦洗Lucene搜索詞

[英]Scrub Lucene search terms with the Standard Analyzer

我們正在根據搜索字詞字符串構建布爾查詢,以搜索我們的Lucene索引。 我希望使用標准分析器(我們用於索引的分析器)分析這些字符串。 例如, foo-bar 1-2-3應該被分解為foobar1-2-3因為Lucene文檔指出連字符導致數字保持在一起但單詞被標記化。 做這個的最好方式是什么?

目前,我正在通過QueryParser運行搜索詞字符串。

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

問題是插入了引號。 例如, foo-bar 1-2-3變為"foo bar"1-2-3 ,它不會返回任何內容,因為Lucene會將foo-bar標記為foobar

我絕對不希望通過用replace刪除引號來解決這種情況,因為我覺得我可能丟失了一些東西或做錯了什么。

實際上,對於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM