首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Lucene 進階搜尋全景圖:布爾、通配、模糊、範圍、域查詢一網打盡

     編輯:Java 相關知識

前言

Lucene 提供豐富的 Query 實現,支援類 Google 的搜尋語法。本文系統整理五大進階查詢類型,並給出對應的 QueryParser 語法與低階 API 兩種使用方式。

一、布爾操作符(QueryParser 語法)

操作符語法示例語義備註
ORJava Lucene並集(預設空格即 OR)至少匹配一個詞
ANDJava AND Lucene交集必須同時包含
NOTJava NOT Lucene差集不能單獨用 NOT Java
++Java Lucene強制包含僅作用於緊後單詞
-Java -Lucene強制排除等同 NOT
// QueryParser 方式
Query q = new QueryParser("title", new StandardAnalyzer()).parse("+Java -Lucene");

二、域搜尋

限定查詢在特定欄位:

// 語法:fieldName:keyword
Query q = new QueryParser("title", new StandardAnalyzer()).parse("title:Lucene AND content:Java");

低階 API 組合:

BooleanQuery.Builder b = new BooleanQuery.Builder();
b.add(new TermQuery(new Term("title", "Lucene")), Occur.MUST);
b.add(new TermQuery(new Term("content", "Java")), Occur.MUST);

三、通配符查詢

通配符匹配規則示例匹配結果
?單字符t?nytiny, tony
*零或多字符Teach*Teach, Teacher, Teaching
// 低階 API(QueryParser 不支援開頭通配)
Query q1 = new WildcardQuery(new Term("title", "tex*"));
Query q2 = new WildcardQuery(new Term("title", "tex?"));
Query q3 = new WildcardQuery(new Term("title", "?ex*"));
效能警告:開頭通配(*abc)會掃描整個詞典,極其緩慢,生產環境慎用或啟用 ReverseStringFilter 反轉索引。

四、模糊查詢

基於Levenshtein 編輯距離,允許拼寫錯誤:

// 語法:term~ 或 term~0.8 (相似度閾值 0~1)
Query q = new FuzzyQuery(new Term("title", "think")); // 編輯距離 ≤ 2
// 低階可調參數
FuzzyQuery fuzzy = new FuzzyQuery(new Term("title", "text"), 2, 0, 50);

五、範圍查詢

適用於數值、日期、字串排序:

// 語法:field:[min TO max] (包含) 或 field:{min TO max} (不包含)
Query q = new QueryParser("birthDay", new StandardAnalyzer()).parse("birthDay:[20000101 TO 20060606]");

// 低階 API(Lucene 4+ 推薦 NumericRangeQuery)
Query numRange = NumericRangeQuery.newIntRange("age", 18, 35, true, true);
Query strRange = TermRangeQuery.newStringRange("name", "A", "M", true, true);

六、綜合實戰:多條件組合搜尋

public TopDocs advancedSearch(IndexSearcher searcher, String keyword, 
                              Integer minAge, Integer maxAge, String category) throws Exception {
    BooleanQuery.Builder builder = new BooleanQuery.Builder();

    // 關鍵詞全文搜尋(標題+內容)
    if (keyword != null) {
        QueryParser qp = new MultiFieldQueryParser(new String[]{"title","content"}, new StandardAnalyzer());
        builder.add(qp.parse(keyword), Occur.MUST);
    }

    // 年齡範圍
    if (minAge != null || maxAge != null) {
        builder.add(NumericRangeQuery.newIntRange("age", minAge, maxAge, true, true), Occur.MUST);
    }

    // 精確分類
    if (category != null) {
        builder.add(new TermQuery(new Term("category", category)), Occur.FILTER); // 不計分,效能更好
    }

    return searcher.search(builder.build(), 20);
}

效能優化清單

  1. 僅作為過濾條件的查詢使用 Occur.FILTER 或 ConstantScoreQuery 避免評分開銷;
  2. 高頻詞(停用詞)查詢前先移除;
  3. 大結果集僅取 Top-N 時使用 TopScoreDocCollector 而非 search(query, n);
  4. 啟用 IndexReader.setDefaultQueryCache 緩存頻繁 Filter。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved