## Lucene查詢語言
<hr>
<div style="text-indent:2em;">
<p>ElasticSearch提供的一些查詢方式(query types)能夠被Lucene的查詢解析器(query parser)語法所支持。由于這個原因,我們來深入學習Lucene查詢語言,了解其廬山真面目吧。</p>
<h3>基礎語法</h3>
<p>用戶使用Lucene進行查詢操作時,輸入的查詢語句會被分解成一個或者多個Term以及邏輯運算符號。一個Term,在Lucene中可以是一個詞,也可以是一個短語(用雙引號括引來的多個詞)。如果事先設定規則:解析查詢語句,那么指定的analyzer就會用來處理查詢語句的每個term形成Query對象。</p>
<br/>
<p>一個Query對象中會存在多個布爾運算符,這些布爾運算符將多個Term關聯起來形成查詢子句。布爾運算符號有如下類型:
<hr style="height:4px;"/>
<ul>
<li><span style="font-family:COURIER;">AND(與)</span>:給定兩個Term(左運算對象和右運算對象),形成一個查詢表達式。只有兩個Term都匹配成功,查詢子句才匹配成功。比如:查詢語句"apache AND lucene"的意思是匹配含apache且含lucene的文檔。</li>
<li><span style="font-family:COURIER;">OR(或)</span>:給定的多個Term,只要其中一個匹配成功,其形成的查詢表達式就匹配成功。比如查詢表達式"apache OR lucene"能夠匹配包含“apache”的文檔,也能匹配包含"lucene"的文檔,還能匹配同時包含這兩個Term的文檔。</li>
<li><span style="font-family:COURIER;">NOT(非)</span>: 這意味著對于與查詢語句匹配的文檔,NOT運算符后面的Term就不能在文檔中出現的。例如:查詢表達式“lucene NOT elasticsearch”就只能匹配包含lucene但是不含elasticsearch的文檔。</li>
</ul>
<br/>
此外,我們也許會用到如下的運算符:
<ul>
<li><b>+</b>這個符號表明:如果想要查詢語句與文檔匹配,那么給定的Term必須出現在文檔中。例如:希望搜索到包含關鍵詞lucene,最好能包含關鍵詞apache的文檔,可以用如下的查詢表達式:"+lucene apache"。</li>
<li><b>-</b>這個符號表明:如果想要查詢語句與文檔匹配,那么給定的Term不能出現在文檔中。例如:希望搜索到包含關鍵詞lucene,但是不含關鍵詞elasticsearch的文檔,可以用如下的查詢表達式:"+lucene -elasticsearch"。</li>
</ul>
如果在Term前沒有指定運算符,那么默認使用OR運算符。<br/>
此外,也是最后一點:查詢表達式可以用小括號組合起來,形成復雜的查詢表達式。比如:
<center><span style="color:gray;font-family:COURIER;background-color:#F7F7F7;">elasticsearch AND (mastering OR book)</span></center>
</p>
<h3>多域查詢</h3>
<p>當然,跟ElasticSearch一樣,Lucene中的所有數據都是存儲在一個個的Field中,多個Field形成一個Document。如果希望查詢指定的Field,就需要在查詢表達式中指定Field Name(此域名非彼域名),后面接一個冒號,緊接著一個查詢表達式。例如:查詢title域中包含關鍵詞elasticsearch的文檔,查詢表達式如下:
<center><span style="color:gray;font-family:COURIER;background-color:#F7F7F7;">title:elasticsearch</span></center>
也可以把多個查詢表達式用于一個域中。例如:查詢title域中含關鍵詞elasticsearch并且含短語“mastering book”的文檔,查詢表達式如下:
<center><span style="color:gray;font-family:COURIER;background-color:#F7F7F7;">title:(+elasticsearch +"mastering book")</span></center>
當然,也可以換一種寫法,作用是一樣的:
<center><span style="color:gray;font-family:COURIER;background-color:#F7F7F7;">+title:elasticsearch +title:"mastering book")</span></center>
</p>
<h3>詞語修飾符</h3>
<p>除了可以應用簡單的關鍵詞和查詢表達式實現標準的域查詢,Lucene還支持往查詢表達式中傳入修飾符使關鍵詞具有變形能力。最常用的修飾符,也是大家都熟知的,就是通配符。Lucene支持?和\*兩種通配符。?可以匹配任意單個字符,而\*能夠匹配多個字符。
</p>
<br/><!--note -->
<div style="height:50px;width:650px;text-indent:0em;">
<div style="float:left;width:13px;height:100%; background:black;">
<img src="../lm.png" height="40px" width="13px" style="margin-top:5px;"/>
</div>
<div style="float:left;width:50px;height:100%;position:relative;">
<img src="../note.png" style="position:absolute; top:20%; "/>
</div>
<div style="float:left; width:550px;height:100%;">
<p style="font-size:13px;"><br/>請注意出于性能考慮,默認的通配符不能是關鍵詞的首字母。</p>
</div>
<div style="float:left;width:13px;height:100%;background:black;">
<img src="../rm.png" height="40px" width="13px" style="margin-top:5px;"/>
</div>
</div>
<br/>
<p>此外,Lucene支持模糊查詢(fuzzy query)和鄰近查詢(proximity query)。語法規則是查詢表達式后面接一個~符號,后面緊跟一個整數。如果查詢表達式是單獨一個Term,這表示我們的搜索關鍵詞可以由Term變形(替換一個字符,添加一個字符,刪除一個字符)而來,即與Term是相似的。這種搜索方式稱為模糊搜索(fuzzy search)。在~符號后面的整數表示最大編輯距離。例如:執行查詢表達式 "writer~2"能夠搜索到含writer和writers的文檔。</p>
<p>當~符號用于一個短語時,~后面的整數表示短語中可接收的最大的詞編輯距離(短語中替換一個詞,添加一個詞,刪除一個詞)。舉個例子,查詢表達式title:"mastering elasticsearch"只能匹配title域中含"mastering elasticsearch"的文檔,而無法匹配含"mastering book elasticsearch"的文檔。但是如果查詢表達式變成title:"mastering elasticsearch"~2,那么兩種文檔就都能夠成功匹配了。</p></br>
<p>此外,我們還可以使用加權(boosting)機制來改變關鍵詞的重要程度。加權機制的語法是一個^符號后面接一個浮點數表示權重。如果權重小于1,就會降低關鍵詞的重要程度。同理,如果權重大于1就會增加關鍵詞的重要程度。默認的加權值為1。可以參考<span style="font-style:oblique"> 第2章 活用用戶查詢語言 </span>的<span style="font-style:oblique"> Lucene默認打分規則詳解 </span>章節部分的內容來了解更多關于加權(boosting)是如何影響打分排序的。</p>
<p>除了上述的功能外,Lucene還支持區間查詢(range searching),其語法是用中括號或者}表示區間。例如:如果我們查詢一個數值域(numeric field),可以用如下查詢表達式:</p>
<p style="color:gray;font-family:COURIER;">price:[10.00 TO 15.00]</p>
<p>這條查詢表達式能查詢到price域的值在10.00到15.00之間的所有文檔。</p>
<p>對于string類型的field,區間查詢也同樣適用。例如:</p>
<p style="color:gray;font-family:COURIER;">name:[Adam TO Adria]</p>
<p>這條查詢表達式能查詢到name域中含關鍵詞Adam到關鍵詞Adria之間關鍵詞(字符串升序,且閉區間)的文檔。</p>
<p>如果希望區間的邊界值不會被搜索到,那么就需要用大括號替換原來的中括號。例如,查詢price域中價格在10.00(10.00要能夠被搜索到)到15.00(15.00不能被搜索到)之間的文檔,就需要用如下的查詢表達式:</p>
<p style="color:gray;font-family:COURIER;">price:[10.00 TO 15.00}</p>
<h3>處理特殊字符</h3>
<p>如果在搜索關鍵詞中出現了如下字符集合中的任意一個字符,就需要用反斜杠(\\)進行轉義。字符集合如下: +, -, &&, || , ! , (,) , { } , [ ] , ^, " , ~, *, ?, : , \, / 。例如,查詢關鍵詞 abc"efg 就需要轉義成 abc\"efg。</div>
</p>
- 前言
- 第1章 認識Elasticsearch
- 認識Apache Lucene
- 熟悉Lucene
- 總體架構
- 分析你的文本
- Lucene查詢語言
- 認識 ElasticSearch
- 基本概念
- ElasticSearch背后的核心理念
- ElasticSearch的工作原理
- 本章小結
- 第2章 強大的用戶查詢語言DSL
- Lucene默認打分算法
- 查詢重寫機制
- 重排序
- 批處理
- 查詢結果的排序
- Update API
- 使用filters優化查詢
- filters和scope在ElasticSearch Faceting模塊的應用
- 本章小結
- 第3章 索引底層控制
- 第4章 探究分布式索引架構
- 選擇恰當的分片數量和分片副本數量
- 路由功能淺談
- 調整集群的分片分配
- 改變分片的默認分配方式
- 查詢的execution preference
- 學以致用
- 本章小結
- 第5章 管理Elasticsearch
- 選擇正確的directory實現類——存儲模塊
- Discovery模塊的配置
- 索引段數據統計
- 理解ElasticSearch的緩存
- 本章小結
- 第6章 應對突發事件
- 第7章 優化用戶體驗
- 第8章 ElasticSearch Java API
- 第9章 開發ElasticSearch插件