天天看點

lucene文法 lucene查詢文法詳解

轉自網址http://hi.baidu.com/expertsearch/blog/item/8d4f7d355a2e413c5ab5f547.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中完整包含的很用引号引起來。

Term Modifiers

Lucene支援在Term中使用通配符來支援模糊查詢。

Wildcard Searches 

Lucene支援單個或者多個字元的通配符查詢,比對單一字元使用符号“?”,比對多個字元使用符号“*”。

“?”通配符将查找所有滿足通過一個字元替換後符合條件的文檔。比如:搜尋“test”和“text”你可以使用:

te?t 

“*”通配符将查詢0個或者多個字元替換後符合條件的。舉例來說,查詢test,tests或者tester,你可以使用一下字元串來搜尋:

test*

當然,你也可以将“*”放在字元的中間

te*t 

注意:你不能将“*”和“?”放在第一個字元來查詢。(Lucene應該是出于性能考慮,是以不支援該功能)

Fuzzy Searches 

Lucene支援基于編輯距離算法的模糊搜尋,你可以使用波浪符号“~”放在查詢詞的後面,比如搜尋一個與“roam”拼寫相近的詞可以使用:

roam~ 

該查詢将尋找類似“foam”和“roams”等的詞語。也可以說是相似度查詢。

Proximity Searches 

Lucene支援指定距離查詢,你可以使用波浪号“~”加數字在查詢詞後。舉例來說搜尋“apache”和“jakarta”距離10個字元以内,你可以使用如下文法:

"jakarta apache"~10 

通過這個文法支援,我們可以單字索引,分詞查詢,分詞完後,滿足每個詞的單字必須間距為0。這樣可以保證100%的召回率,但是在索引方面将造成索引臃腫,同時查詢速度也将在某程度上降低,一般來說,在150W文章資料到200W資料的時候性能将會明顯的降低。

Range Searches 

範圍查詢允許你指定某個字段最大值和最小值,查詢在二者之間的所有文檔。範圍查詢可以包含或者不包含最大值和最小值,排序是按照字典順序來排序的。

mod_date:[20020101 TO 20030101] 

這個将查找滿足mode_date字段在大于等于20020101,小于等于20030101範圍的所有文檔,注意:範圍查詢并不是為日期字段專設的,你也可以對非日期字段進行範圍查詢。

title:{Aida TO Carmen} 

這個将查找所有标題在Aida和Carmen之間但不包含Aida和Carmen的文檔。包含最大值和最小值的查詢使用方括号,排除則使用花括号。

Boosting a Term 

Lucene支援給不同的查詢詞設定不同的權重。設定權重使用“^”符号,将“^”放于查詢詞的尾部,同時跟上權重值,權重因子越大,該詞越重要。設定權重允許你通過給不同的查詢詞設定不同的權重來影響文檔的相關性,假如你在搜尋:

jakarta apache 

如果你認為“jakarta”在查詢時中更加重要,你可以使用如下文法:

jakarta^4 apache 

這将使含有Jakarta的文檔具有更高的相關性,同樣你也可以給短語設定權重如下:

"jakarta apache"^4 "jakarta lucene" 

在預設情況下,權重因子為1,當然權重因子也可以小于1。

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\)\:2 

Lucene搜尋結果比對度設定:

方法一: 

Sort sort = new Sort(new SortField[]{new SortField("字段名1" , SortField.SCORE , false),new SortField("字段名2" , SortField.SCORE, false),new SortField("字段名3" , SortField.SCORE, false)});