注意:使用QueryParser查詢,關鍵詞是會被分詞的,若是不須要分詞,能夠選擇使用Lucene提供的API查詢類。html
Lucene提供了豐富的API來組合定製你所須要的查詢器,同時也能夠利用Query Parser提供的強大的查詢語法解析來構造你想要的查詢器。本文章詳細的介紹了Lucene的查詢語法。經過Java語法分析器把一個查詢字符串解析成 Lucene的查詢器。在你選擇使用Query Parser前,請考慮如下事項:
若是你打算在程序中拼接查詢語法串而後再利用Query Parser轉換,那麼強烈建議你利用相應的API來本身構造查詢器。也就是說,Query Parser是爲手工輸入高級查詢設計的,而不是爲程序拼接語法串而設計的。不分詞的字段也最好經過相應的API添加到查詢器中,而不是經過Query Parser。Query Parser 使用的Analyser分析器,做用是將用戶手工輸入的文本轉化爲相應的Term。若是一個字段的值是經過程序生成的(例如日期字段,關鍵詞字段等),那 麼在查詢的時候也應該保持先後一致,利用程序生成相應的格式來查詢。
在查詢的目標中,若是字段所有是程序生成的文本,(例如補齊的日期字段等),最好使用Query Parser以便查詢的時候也是一致的格式。至於其它的,例如日期範圍查詢,關鍵字查詢等,最好調用相應的API來構建查詢器。目標字段中若是僅僅擁有有 限的枚舉值時,最好經過下拉列表提供給用戶選擇,而後利用TermQuery添加到查詢器中,而不是而其拼接到查詢字符串而後利用Query Parser來解析。
Terms
一個查詢將分解爲若干Term以及操做符,有兩種Term,其一是單一Term,其二爲短語。單一Term是通過分析器分詞後的最小單元,他就是一個簡單 的詞,例如「Test」和「Hello」。短語則是一組被雙引號括起來的一組詞,例如:「Hello dolly」,多個Term能夠經過布爾操做合併在一個更加複雜的查詢器中。
注意:通常來講,建立索引的分析器和查詢的分析器最好保持一致(固然也有特殊狀況,好比單字索引,分詞組合查詢),因此選擇一個不會干擾查詢詞的分析器是很重要的。
Fields
Lucene支持多字段數據,當你在查詢的時候你能夠指定一個字段查詢,也可使用默認的字段。你可使用 字段名 + 「:」 + 查詢詞來指定字段名搜索。舉個例子,讓咱們假定Lucene的索引中含有兩個字段,Title字段和Text字段,其中Text字段是默認字段,當你想找 到一篇文檔其中標題包含「The Right Way」同時文本中包含「go」,你能夠輸入:
title:"The Right Way" AND text:go
或者:
title:" The Right Way " AND go
若是字段是默認字段的話,在查詢語法中能夠不須要顯式指定。注意,使用默認字段有可能會形成以下的結果:
title:Do it right
以上查詢將查找標題中含有「Do」,Text字段字段中含有「it」和「right」的文檔,由於Text是默認字段,因此若是想要查找Title中完整包含的很用引號引發來。java
2、模糊查詢
Term Modifiers
Lucene支持在Term中使用通配符來支持模糊查詢。web
Wildcard Searches [類:org.apache.lucene.search.WildcardQuery]
Lucene支持單個或者多個字符的通配符查詢,匹配單一字符使用符號「?」,匹配多個字符使用符號「*」。
「?」通配符將查找全部知足經過一個字符替換後符合條件的文檔。好比:搜索「test」和「text」你可使用:
te?t
「*」通配符將查詢0個或者多個字符替換後符合條件的。舉例來講,查詢test,tests或者tester,你可使用一下字符串來搜索:
test*
固然,你也能夠將「*」放在字符的中間
te*t
注意:你不能將「*」和「?」放在第一個字符來查詢。(Lucene應該是出於性能考慮,因此不支持該功能)
Fuzzy Searches [org.apache.lucene.search.FuzzyQuery]
Lucene支持基於編輯距離算法的模糊搜索,你可使用波浪符號「~」放在查詢詞的後面,好比搜索一個與「roam」拼寫相近的詞可使用:
roam~
該查詢將尋找相似「foam」和「roams」等的詞語。也能夠說是類似度查詢。
Proximity Searches [org.apache.lucene.search.PrefixQuery]
Lucene支持指定距離查詢,你可使用波浪號「~」加數字在查詢詞後。舉例來講搜索「apache」和「jakarta」距離10個字符之內,你可使用以下語法:
"jakarta apache"~10
經過這個語法支持,咱們能夠單字索引,分詞查詢,分詞完後,知足每一個詞的單字必須間距爲1。這樣能夠保證100%的召回率,可是在索引方面將形成索引臃腫,同時查詢速度也將在某程度上下降,通常來講,在150W文章數據到200W數據的時候性能將會明顯的下降。
Range Searches [org.apache.lucene.search.RangeQuery]
範圍查詢容許你指定某個字段最大值和最小值,查詢在兩者之間的全部文檔。範圍查詢能夠包含或者不包含最大值和最小值,排序是按照字典順序來排序的。
mod_date:[20020101 TO 20030101]
這個將查找知足mode_date字段在大於等於20020101,小於等於20030101範圍的全部文檔,注意:範圍查詢並非爲日期字段專設的,你也能夠對非日期字段進行範圍查詢。
title:{Aida TO Carmen}
這個將查找全部標題在Aida和Carmen之間但不包含Aida和Carmen的文檔。包含最大值和最小值的查詢使用方括號,排除則使用花括號。算法
3、優先級
Boosting a Term
Lucene支持給不一樣的查詢詞設置不一樣的權重。設置權重使用「^」符號,將「^」放於查詢詞的尾部,同時跟上權重值,權重因子越大,該詞越重要。設置權重容許你經過給不一樣的查詢詞設置不一樣的權重來影響文檔的相關性,假如你在搜索:
jakarta apache
若是你認爲「jakarta」在查詢時中更加劇要,你可使用以下語法:
jakarta^4 apache
這將使含有Jakarta的文檔具備更高的相關性,一樣你也能夠給短語設置權重以下:
"jakarta apache"^4 "jakarta lucene"
在默認狀況下,權重因子爲1,固然權重因子也能夠小於1。apache
4、Term操做符
Boolean operators
布爾操做符能夠將多個Term合併爲一個複雜的邏輯查詢。Lucene支持AND,
+,OR,NOT, -做爲操做符號。注意,全部的符號必須爲大寫。
OR
OR操做符默認的鏈接操做符。這意味着,當沒有給多個Term顯式指定操做符時,將使用OR,只要其中一個Term含有,則能夠查詢出文檔,這跟邏輯符 號||的意思類似。假設咱們查詢一個文檔含有「jakarta apache」或者「jakarta」時,咱們可使用以下語法:
"jakarta apache" jakarta
或者
"jakarta apache" OR jakarta
AND
AND操做符規定必須全部的Term都出現才能知足查詢條件,這跟邏輯符號&&意思類似。若是咱們要搜索一個文檔中同時含有「jakarta apache」和「jakarta lucene」,咱們可使用以下語法:
"jakarta apache" AND "jakarta lucene"
+
+操做符規定在其後的Term必須出如今文檔中,也就是查詢詞中的MUST屬性。舉個例子來講,當咱們要查詢一個文檔必須包含「jakarta」,同時能夠包含也能夠不包含「lucene」時,咱們可使用以下語法:
+jakarta apache
NOT
NOT操做符規定查詢的文檔必須不包含NOT以後的Term,這跟邏輯符號中的!類似。當咱們要搜索一篇文檔中必須含有「jakarta apache」同時不能含有「Jakarta lucene」時,咱們可使用以下查詢;
"jakarta apache" NOT "jakarta lucene"
注意:NOT操做符不能使用在單獨Term中,舉例來講,如下查詢將返回無結果:
NOT "jakarta apache"
-
-操做符排除了包含其後Term的文檔,跟NOT有點相似,假設咱們要搜索「Jakarta apache」但不包含「Jakarta lucene」時,咱們使用以下語法:
"jakarta apache" -"jakarta lucene"
Grouping
Lucene支持使用圓括號來將查詢表達式分組,這將在控制布爾控制查詢中很是有用。舉例來講:當搜索必須含有「website」,另外必須含有「jakarta」和「apache」之一,咱們能夠用以下語法:
(jakarta OR apache) AND website
這種語法對消除歧義,確保查詢表達式的正確性具備很大的意義。
Field Grouping
Lucene支持對字段用圓括號來進行分組,當咱們要查詢標題中含有「return」和「pink ranther」時,咱們可使用以下語法:
title:(+return +"pink panther")
Escaping Special Characters
Lucene支持轉義查詢中的特殊字符,如下是Lucene的特殊字符清單:
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \
轉義特殊字符咱們可使用符號「\」放於字符以前。好比咱們要搜索(1+1):2,咱們可使用以下語法:
\(1\+1\)\:2api
Tips: QueryParser.escape(q) 可轉換q中含有查詢關鍵字的字符!如:* ,? 等性能
英文原文地址:http://lucene.apache.org/java/2_4_0/queryparsersyntax.htmlspa
修改自:http://hi.baidu.com/expertsearch/blog/item/8d4f7d355a2e413c5ab5f547.html.net
轉自:https://www.oschina.net/question/1092_560設計