本篇主要講Elasticsearch的_search API的簡單使用, 包括在URI中拼接請求體的方式實現查詢、對主要查詢參數的含義和使用進行演示, 還講到了timeout超時機制的作用和使用方法. ...
目錄
1 Search API的基本用法
1.1 查詢所有數據
GET _search
1.2 響應信息說明
{
"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部分 .
版權聲明
作者: 馬瘦風
出處: 博客園 馬瘦風的博客