上篇回顧
子曰,溫故而知新,可以為師也。學習的過程就是不斷的回顧,總結,總結,再總結。首先,一起來回顧下上篇 search API中的內容。
為了能夠更透徹的理解 rest client search API 的使用,我專門整理了相關對象之間的關系圖,一起來看下。

由上圖看出, QueryBuilder 是整個查詢操作的核心,決定了查詢什么樣的數據和期望得到什么結果這些核心的問題。
QueryBuilder 只是一個接口,需要具體的實體類才可以。那么如何創建 QueryBuilder 的實例呢?有兩種方式
- 通過
QueryBuilder實現類的構造函數 - 使用
QueryBuilders工具類創建
Building Queries
下面就來看下常用的查詢及其 API 有哪些
匹配所有的查詢
查詢語句如下
GET /_search
{
"query": {
"match_all": {}
}
}
對應的 QueryBuilder Class 為 MatchAllQueryBuilder
具體方法為 QueryBuilders.matchAllQuery()
全文查詢 Full Text Queries
什么是全文查詢?
像使用 match 或者 query_string 這樣的高層查詢都屬於全文查詢,
- 查詢 日期(
date) 或整數(integer) 字段,會將查詢字符串分別作為日期或整數對待。 - 查詢一個(
not_analyzed)未分析的精確值字符串字段,會將整個查詢字符串作為單個詞項對待。 - 查詢一個(
analyzed)已分析的全文字段,會先將查詢字符串傳遞到一個合適的分析器,然后生成一個供查詢的詞項列表
組成了詞項列表,后面就會對每個詞項逐一執行底層查詢,將查詢結果合並,並且為每個文檔生成最終的相關度評分。
Match
match 查詢的單個詞的步驟是什么?
- 檢查字段類型,查看字段是
analyzed,not_analyzed - 分析查詢字符串,如果只有一個單詞項,
match查詢在執行時就會是單個底層的term查詢 - 查找匹配的文檔,會在倒排索引中查找匹配文檔,然后獲取一組包含該項的文檔
- 為每個文檔評分
構建 Match 查詢
match 查詢可以接受 text/numeric/dates 格式的參數,分析,並構建一個查詢。
GET /_search
{
"query": {
"match" : {
"message" : "this is a test"
}
}
}
上面的實例中 message 是一個字段名。
對應的 QueryBuilder class : MatchQueryBuilder
具體方法 : QueryBuilders.matchQuery()
全文查詢 API 列表
全部的 API 列表如下(鏈接均指向 elasticsearch 官網)
基於詞項的查詢
這種類型的查詢不需要分析,它們是對單個詞項操作,只是在倒排索引中查找准確的詞項(精確匹配)並且使用 TF/IDF 算法為每個包含詞項的文檔計算相關度評分 _score。
Term
term 查詢可用作精確值匹配,精確值的類型則可以是數字,時間,布爾類型,或者是那些 not_analyzed 的字符串。
對應的 QueryBuilder class 是TermQueryBuilder
具體方法是 QueryBuilders.termQuery()
Terms
terms 查詢允許指定多個值進行匹配。如果這個字段包含了指定值中的任何一個值,就表示該文檔滿足條件。
對應的 QueryBuilder class 是 TermsQueryBuilder
具體方法是 QueryBuilders.termsQuery()
Wildcard
wildcard 通配符查詢是一種底層基於詞的查詢,它允許指定匹配的正則表達式。而且它使用的是標准的 shell 通配符查詢:
?匹配任意字符*匹配 0 個或多個字符
wildcard 需要掃描倒排索引中的詞列表才能找到所有匹配的詞,然后依次獲取每個詞相關的文檔 ID。
由於通配符和正則表達式只能在查詢時才能完成,因此查詢效率會比較低,在需要高性能的場合,應當謹慎使用。
對應的 QueryBuilder class 是 WildcardQueryBuilder
具體方法是 QueryBuilders.wildcardQuery()
基於詞項 API 列表
復合查詢
什么是復合查詢?
復合查詢會將其他的復合查詢或者葉查詢包裹起來,以嵌套的形式展示和執行,得到的結果也是對各個子查詢結果和分數的合並。可以分為下面幾種:
-
經常用在使用 filter 的場合,所有匹配的文檔分數都是一個不變的常量
-
可以將多個葉查詢和組合查詢再組合起來,可接受的參數如下
- must : 文檔必須匹配這些條件才能被包含進來
must_not文檔必須不匹配才能被包含進來should如果滿足其中的任何語句,都會增加分數;即使不滿足,也沒有影響filter以過濾模式進行,不評分,但是必須匹配
-
叫做分離最大化查詢,它會將任何與查詢匹配的文檔都作為結果返回,但是只是將其中最佳匹配的評分作為最終的評分返回。
-
允許為每個與主查詢匹配的文檔應用一個函數,可用來改變甚至替換原始的評分
-
用來控制(提高或降低)復合查詢中子查詢的權重。
復合查詢列表
特殊查詢
Wrapper Query
這里比較重要的一個是 Wrapper Query,是說可以接受任何其他 base64 編碼的字符串作為子查詢。
主要應用場合就是在 Rest High-Level REST client 中接受 json 字符串作為參數。比如使用 gson 等 json 庫將要查詢的語句拼接好,直接塞到 Wrapper Query 中查詢就可以了,非常方便。
Wrapper Query 對應的 QueryBuilder class 是WrapperQueryBuilder
具體方法是 QueryBuilders.wrapperQuery()
小結
本文對 elasticsearch rest high client 中的查詢構建進行了總結和整理,對常用的 API 做了簡要的介紹。讀者如果要查看完整的構建查詢的 API 列表,可參考此處
