ES 19 - Elasticsearch的檢索語法(_search API的使用)

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時間) 內, 將搜索到的數據 (可能只搜索到了部分數據, 也可能搜索到了所有數據) 當即返回給客戶端, 而不是等待查詢操做徹底完成後再返回.html

—— 確保在指定時間內返回數據, 不管查詢是否完成.java

ES的搜索默認不開啓timeout, 查詢持續的時間 (latency) 將根據查詢的完整性 (completeness) 自動延遲, 能夠手動指定timeout, 使用示例:shell

GET _search?timeout=10ms
# 可用的單位: timeout=10ms | timeout=1s | timeout=1m

舉例說明:編程

Elasticsearch能在1分鐘內查詢到符合條件的所有2000條數據, 在指定timeout=10以後, 就會在10ms時返回查詢到的部分結果, 此時可能只查詢到了部分數據.json

1.4 查詢多索引和多類型中的數據

(1) 一次性搜索多個索引(multi-index) 中的數據:api

# 搜索指定一個index下的全部數據
GET index1/_search

# 同時搜索兩個index下的數據
GET index1,index2/_search

# 按照通配符匹配搜索多個index下的數據
GET *1,*2/_search

(2) 和多個類型(multi-type)在的數據:瀏覽器

注意事項: 在Elasticsearch 6.x以前的版本中, 支持一個index下有多個type, 在6.x以後的版本再也不支持.bash

# 搜索一個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 默認的多個條件之間的關係, 能夠是 ANDOR. 默認是 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_fetchquery_then_fetch, 默認是query_then_fetch.
allow_partial_search_results 若是請求將產生部分結果, 設置爲false用來返回總體故障. 默認爲true, 這將在超時或部分失敗的狀況下, 返回部分結果.
能夠經過集羣中的search.default_allow_partial_results來設置此參數.

2.3 URI Search用法示例

// 查詢索引index1中、類型爲type一、field1=test的全部文檔
GET index1/type1/_search?q=field1:test

// 查詢索引index1中、類型爲type一、必須知足field1=test的全部文檔
GET index1/type1/_search?q=+test_field:test

// 查詢索引index1中、類型爲type一、不知足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部分 .

版權聲明

做者: 馬瘦風

出處: 博客園 馬瘦風的博客

感謝閱讀, 若是文章有幫助或啓發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜

本文版權歸博主全部, 歡迎轉載, 但 [必須在文章頁面明顯位置給出原文連接], 不然博主保留追究相關人員法律責任的權利.

相關文章
相關標籤/搜索