ES 19 - Elasticsearch的檢索語法(_search API的使用)
1 Search API的基本用法
1.1 查詢所有資料
GET _search
1.2 響應資訊說明
{ "took": 6, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 10,// 本次搜尋命中(搜尋到)的結果總數 "max_score": 1, "hits": [// 預設顯示查詢結果中的前10條記錄, 根據_score降序排序 { "_index": ".kibana", "_type": "config", "_id": "5.6.10", "_score": 1,// 相關度得分, 越相關, 分值越大, 排位越靠前 "_source": { "buildNum": 14695 } } ] } } { "took" : 346,// 整個檢索消耗的時間, 單位是毫秒. 包括執行緒池中的等待時間、叢集中分散式搜尋+收集結果的時間 "timed_out" : false,// 預設不啟用超時機制, 若啟用, 需要設定具體的時間值 "_shards" : {// 搜尋用到的shard數, 以及成功/失敗的shard數 "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0// 一個Shard的Primary和Replicas都掛掉, 它才被認為失敗 }, "hits" : { "total" : 10,// 本次搜尋命中(搜尋到)的結果總數 "max_score" : 1.0, // 本次搜尋的所有結果中, 最大的相關度分數 "hits" : [// 預設顯示查詢結果中的前10條記錄, 根據_score降序排序 { "_index" : "book_shop", "_type" : "books", "_id" : "2", "_score" : 1.0,// 相關度得分, 越相關, 分值越大, 排位越靠前 "_source" : { "name" : "Java程式設計思想", "category" : "程式語言", "author" : "Bruce Eckel", "price" : 105.0, "publisher" : "機械工業出版社", "date" : "2016-01-01" } } ] } }
1.3 timeout超時機制
指定每個Shard必須在規定的時間 (也就是指定的timeout時間) 內, 將搜尋到的資料 (可能只搜尋到了部分資料, 也可能搜尋到了全部資料) 立即返回給客戶端, 而不是等待查詢操作完全完成後再返回.
—— 確保在指定時間內返回資料, 無論查詢是否完成.
ES的搜尋預設不開啟timeout, 查詢持續的時間 (latency) 將根據查詢的完整性 (completeness) 自動延遲, 可以手動指定timeout, 使用示例:
GET _search?timeout=10ms # 可用的單位: timeout=10ms | timeout=1s | timeout=1m
舉例說明:
Elasticsearch能在1分鐘內查詢到符合條件的全部2000條資料, 在指定timeout=10
之後, 就會在10ms時返回查詢到的部分結果, 此時可能只查詢到了部分資料.
1.4 查詢多索引和多型別中的資料
(1) 一次性搜尋多個索引(multi-index) 中的資料:
# 搜尋指定一個index下的所有資料 GET index1/_search # 同時搜尋兩個index下的資料 GET index1,index2/_search # 按照萬用字元匹配搜尋多個index下的資料 GET *1,*2/_search
(2) 和多個型別(multi-type)在的資料:
注意事項: 在Elasticsearch 6.x之前的版本中, 支援一個index下有多個type, 在6.x之後的版本不再支援.
# 搜尋一個index下指定的type的資料 GET index1/type1/_search # 搜尋一個index下多個type的資料 GET index1/type1,type2/_search # 搜尋多個index下的多個type的資料 GET index1,index2/type1,type2/_search # _all, 搜尋所有index下指定type的資料 GET _all/type1,type2/_search
2 URI Search的用法
Elasticsearch支援通過在URI中攜帶請求引數執行搜尋.
2.1 GET請求攜帶引數查詢
比如要進行分頁查詢:
GET _search { "from": 0, "size": 10 }
HTTP協議中一般不允許GET請求攜帶請求體 (Request Body), 但由於GET更加符合查詢資料的操作, 因此可以攜帶Request Body. 而很多瀏覽器也都支援GET + Request Body模式.
如果遇到不支援GET + Request Body模式的場景, 也可以用POST方式查詢, 比如:
POST _search { "from":0, "size":10 }
或者使用拼接請求引數的方式進行查詢:
GET _search?from=0&size=10
上述拼接的請求引數就是Query String, 這個串拼接的欄位內容都是String, Elacticsearch底層會對各個field的型別進行對映.
2.2 URI Search的引數列表
引數 | 使用方法 |
---|---|
q
|
查詢字串. |
df
|
查詢中沒有定義字首時, 預設的搜尋欄位. |
analyzer
|
分析查詢字串所使用的分析器的名稱. |
lowercase_expanded_terms
|
搜尋時忽略大小寫標識, 預設為true
. |
analyze_wildcard
|
萬用字元或字首查詢是否被分析, 預設為false
. |
batched_reduce_size
|
協調節點需要減少的分片結果數. 當分片數量很多時, 會產生很大的記憶體開銷, 這個引數用來當做保護機制. |
default_operator
|
預設的多個條件之間的關係, 可以是AND
或OR
. 預設是OR
. |
lenient
|
如果設定為true
, 欄位型別轉換失敗時將忽略處理. 預設為false
. |
explain
|
在每個返回結果中, 將包含評分機制的詳細計算描述. |
_source
|
是否包含元資料, 同時支援_source_incude
和_source_exclude
. |
stored_fields
|
選擇查詢到的文件的指定欄位, 多個之間用","分隔. 若不指定任何欄位, 就不會返回任何欄位. |
sort
|
根據欄位名排序. 可以是fieldName
, 或fieldName:desc
, 或fieldName:asc
, 或_score
(給予分數的排序). 可以有多個排序引數, 要注意各引數之間的順序. |
track_scores
|
跟蹤評分. 排序時, 設定為true
後將跟蹤評分情況, 並在返回的結果中攜帶評分資訊. |
track_total_hits
|
設定為false
, 禁止跟蹤每個查詢的結果總數. 預設為true
, 即統計搜尋到的結果總數. |
timeout
|
搜尋超時, 在指定的時間內執行搜尋請求, 並在超時時間到期時返回查詢到的已有結果. 預設無超時. |
terminate_after
|
每個分片搜尋的最大文件數, 如果達到此值, 即使搜尋尚未結束, 當前分片將提前終止搜尋. 如果設定, 響應資訊中將攜帶一個boolean型別的 terminated_early
欄位, 表示查詢提前終止了. 預設沒有設定. |
from
|
從所有返回結果中的第幾條開始顯示, 預設為0
. |
size
|
搜尋結果返回的條數. 預設為10
, 即返回前10條. |
search_type
|
搜尋的型別, 可以是dfs_query_then_fetch
或query_then_fetch
, 預設是query_then_fetch
. |
allow_partial_search_results
|
如果請求將產生部分結果, 設定為false
用來返回整體故障. 預設為true
, 這將在超時或部分失敗的情況下, 返回部分結果.可以通過叢集中的 search.default_allow_partial_results
來設定此引數. |
2.3 URI Search用法示例
// 查詢索引index1中、型別為type1、field1=test的所有文件 GET index1/type1/_search?q=field1:test // 查詢索引index1中、型別為type1、必須滿足field1=test的所有文件 GET index1/type1/_search?q=+test_field:test // 查詢索引index1中、型別為type1、不滿足field1=test的所有文件 GET index1/type1/_search?q=-test_field:test // 如果我們只想知道是否存在與查詢條件相匹配的文件, 而對文件的具體資訊不感興趣, 此時可以設定size=0. // 還可以設定terminate_after=1, 指明只要在每個shard中找到第一個匹配的文件, 就終止查詢: GET _search?q=field1:test&size=0&terminate_after=1
2.4 不指定field時的搜尋原理
GET index1/type1/_search?q=test // 同樣, 可以使用"+"或"-"來控制是否包含某個關鍵字, 比如: 查詢不包含java的所有文件: GET shop/it_book/_search?q=-java
Elasticsearch預設為每個文件配置了_all
元欄位, 將各個文件的所有field的值用字串拼接起來, 這個長字串就作為_all
欄位的值, 同時建立索引.
查詢時, 如果不指定關鍵字所屬的field, ES將從_all
欄位中搜索, 所有文件中只要存在field包含指定的關鍵字, 就算作匹配, 並將作為結果返回.
示例:
// 文件內容如下: { "name": "Java併發程式設計的藝術", "author": "方騰飛", "date": "2015-07", "publisher": "機械工業出版社" } // 搜尋條件 GET shop/it_book/_search?q=java // 該文件_all欄位的值為: "Java併發程式設計的藝術 方騰飛 2015-07 機械工業出版社", _all欄位中包含java, 所以能夠匹配.
說明: 生產環境中不建議開啟_all
, 也不建議通過_all
欄位進行查詢操作.
==> **在Elasticsearch 6.0版本中, _all欄位已經被禁用了.** 替代方案可以參考這篇文章中的第3部分 .
版權宣告
作者:馬瘦風
出處: 部落格園馬瘦風的部落格
感謝閱讀, 如果文章有幫助或啟發到你, 點個[] 或 [] 吧:stuck_out_tongue_winking_eye:
本文版權歸博主所有, 歡迎轉載, 但[必須在文章頁面明顯位置給出原文連結] , 否則博主保留追究相關人員法律責任的權利.