轉載請注明出處:[http://blog.csdn.net/xiaojimanman/article/details/42969443](http://blog.csdn.net/xiaojimanman/article/details/42969443)
在Lucene索引的搜索過程中,構建Query對象是一個十分重要的過程。對于Query的理解,可以把它想象成數據庫SQL查詢語句中的where條件(當然Query的功能要比sql強大很多),在這篇博客中,我們將重點介紹幾種常用的Query子類:**QueryParser**、?**MultiFieldQueryParser**、**TermQuery?**、**PrefixQuery**、?**PhraseQuery**、?**WildcardQuery**、?
**TermRangeQuery**、?**NumericRangeQuery**、?**BooleanQuery**。
這篇博客稍微和前面的排版不同,先分別對幾個類做簡單介紹,然后在給出具體的demo程序,如若對其中的某些介紹不理解,可以先閱讀后面的demo程序再看前面的介紹。
**QueryParser**
QueryParser主要用于對單個域搜索時創建查詢query,QueryParser的構造方法需指定具體的域名和分詞方法,lucene不同版本,創建的Query對象會略有不同,具體不同還請參照博客:[關于QueryParser類前后修改](http://blog.csdn.net/xiaojimanman/article/details/16972661)。
**MultiFieldQueryParser**
MultiFieldQueryParser可以想象成QueryParser的升級版,QueryParser主要用于單個域的搜索,而MultiFieldQueryParser則用于多個域的搜索,其構造方法和具體使用和QueryParser類似。
**TermQuery**
TermQuery重要對一個Term(最小的索引塊,包含一個field名和值),TermQuery可以用于對關鍵字域查詢時Query的創建,比如分類、文檔唯一ID等。
**PrefixQuery**
PrefixQuery前綴查詢字符串的構建,其效果和“abc*”這種通配符使用WildcardQuery構建Query類似;PrefixQuery只需要前綴指定的若干個字符相同即可,如PrefixQuery(new Term("", "lu")),將會匹配lucene、luke等。
**PhraseQuery**
PhraseQuery短語搜索,它可以指定關鍵詞之間的最大距離,如下面demo程序中,指定了“基于”“案例”這兩個詞之間最大的距離為2,一旦文檔中,這兩個詞的具體大于2就不滿足條件。
**WildcardQuery**
WildcardQuery通配符搜索,可以想象是PrefixQuery的升級版,WildcardQuery提供了更細的控制和更大的靈活行,lucene中有* ? 這兩個通配符,*表示匹配任意多個字符,?表示匹配一個任意字符。如lu*e可以和lucene、luke匹配;lu?e可以和luke匹配,但和lucene卻不匹配。
**TermRangeQuery**
TermRangeQuery字符串范圍搜索,在創建時一般有5個參數分別是 域名、域下限值、域上限值、是否包括下限、是否包括上限,這個和下面的NumericRangeQuery的參數含義相同。
**NumericRangeQuery**
NumericRangeQuery數字范圍搜索,它針對不同的數據類型(int、float、double),提供的不同的方法,參數含義參照TermRangeQuery。
**BooleanQuery**
上面介紹的Query子類幾乎都是針對單個域或多個域單個關鍵字的,那多個域不同關鍵字有該如何處理?多個Query對象又如何組成一個Query對象?這些BooleanQuery都可以實現,BooleanQuery可以嵌套非常復雜的查詢,其和布爾運算類似,提供與(Occur.MUST)、或(Occur.SHOULD)、非(Occur.MUST_NOT)三種邏輯關系。
當然lucene中提供的Query子類還有很多,這里就只簡單的介紹了幾種比較常用的,剩下的如在以后的實際項目中遇到再做介紹學習。
**Query測試demo**
~~~
/**
*@Description: Query學習demo
*/
package com.lulei.lucene.study;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.Version;
public class QueryStudy {
public static void main(String[] args) throws Exception {
//Query過程中使用的分詞器
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);
//搜索詞
String keyValue = "基于lucene的案例開發";
// keyValue = "基于lucene的案例開發 更多內容請訪問:http://blog.csdn.net/xiaojimanman/article/category/2841877";
//將搜索詞進行下轉義,如果搜索詞中沒有lucene中的特殊字符,可以不進行轉義
String key = LuceneKey.escapeLuceneKey(keyValue);
//單個搜索域
String field = "content";
//多個搜索域
String []fields = {"name" , "content"};
Query query = null;
//對單個域構建查詢語句
QueryParser parse = new QueryParser(Version.LUCENE_43, field, analyzer);
query = parse.parse(key);
System.out.println(QueryParser.class);
System.out.println(query.toString());
System.out.println("--------------------------------");
//對多個域創建查詢語句
MultiFieldQueryParser parse1 = new MultiFieldQueryParser(Version.LUCENE_43, fields, analyzer);
query = parse1.parse(key);
System.out.println(MultiFieldQueryParser.class);
System.out.println(query.toString());
System.out.println("--------------------------------");
//詞條搜索
query = new TermQuery(new Term(field, key));
System.out.println(query.getClass());
System.out.println(query.toString());
System.out.println("--------------------------------");
//前綴搜索
query = new PrefixQuery(new Term(field, key));
System.out.println(query.getClass());
System.out.println(query.toString());
System.out.println("--------------------------------");
//短語搜索
PhraseQuery query1 = new PhraseQuery();
//設置短語間允許的最大間隔
query1.setSlop(2);
query1.add(new Term("content", "基于"));
query1.add(new Term("content", "案例"));
System.out.println(query1.getClass());
System.out.println(query1.toString());
System.out.println("--------------------------------");
//通配符搜索
query = new WildcardQuery(new Term(field, "基于?"));
System.out.println(query.getClass());
System.out.println(query.toString());
System.out.println("--------------------------------");
//字符串范圍搜索
query = TermRangeQuery.newStringRange(field, "abc", "azz", true, false);
System.out.println(query.getClass());
System.out.println(query.toString());
//int范圍搜索
query = NumericRangeQuery.newIntRange("star", 0, 3, false, false);
System.out.println(query.getClass() + "\tint");
System.out.println(query.toString());
//float范圍搜索
query = NumericRangeQuery.newFloatRange("star", 0.0f, 3.0f, false, false);
System.out.println(query.getClass() + "\tfloat");
System.out.println(query.toString());
//double范圍搜索
query = NumericRangeQuery.newDoubleRange("star", 0.0, 3d, false, false);
System.out.println(query.getClass() + "\tdouble");
System.out.println(query.toString());
System.out.println("--------------------------------");
//BooleanQuery
BooleanQuery query2 = new BooleanQuery();
query2.add(new TermQuery(new Term("content", "基于")), Occur.SHOULD);
query2.add(new TermQuery(new Term("name", "lucene")), Occur.MUST);
query2.add(new TermQuery(new Term("star", "3")), Occur.MUST_NOT);
System.out.println(query2.getClass());
System.out.println(query2.toString());
System.out.println("--------------------------------");
}
}
~~~
上述demo程序的運行截圖如下:

關于上述Query的意思以及查詢索引得到的結果,這里就不再做介紹,如對其感興趣可以自己按照前面的幾篇博客,創建對應索引文件以及編寫搜索程序。
ps:最近發現其他網站可能會對博客轉載,上面并沒有源鏈接,如想查看更多關于 [基于lucene的案例開發](http://blog.csdn.net/xiaojimanman/article/category/2841877) 請[點擊這里](http://blog.csdn.net/xiaojimanman/article/category/2841877)。或訪問網址http://blog.csdn.net/xiaojimanman/article/category/2841877
- 前言
- 寫在開始之前
- lucene初始認知
- 索引數學模型
- 索引文件結構
- 創建索引
- 搜索索引
- 分詞器介紹
- Query查詢
- IndexSearcher中檢索方法
- 更新說明
- 案例初識
- JsonUtil & XmlUtil
- 基ClassUtil & CharsetUtil
- ParseUtil & ParseRequest
- 數據庫連接池
- 實現實時索引基本原理
- 實時索引管理類IndexManager
- 實時索引的檢索
- 實時索引的修改
- 查詢語句創建PackQuery
- 縱橫小說更新列表頁抓取
- 縱橫小說簡介頁采集
- 縱橫小說章節列表采集
- 縱橫小說閱讀頁采集
- 縱橫小說數據庫設計
- 縱橫小說數據庫操作
- 縱橫小說分布式采集