天天看點

ES 19 - 查詢Elasticsearch中的資料 (基于_search API進行檢索)

本篇主要講Elasticsearch的_search API的簡單使用, 包括在URI中拼接請求體的方式實作查詢、對主要查詢參數的含義和使用進行示範, 還講到了timeout逾時機制的作用和使用方法.

目錄

  • 1 Search API的基本用法
    • 1.1 查詢所有資料
    • 1.2 響應資訊說明
    • 1.3 timeout逾時機制
    • 1.4 查詢多索引和多類型中的資料
  • 2 URI Search的用法
    • 2.1 GET請求攜帶參數查詢
    • 2.2 URI Search的參數清單
    • 2.3 URI Search用法示例
    • 2.4 不指定field時的搜尋原理
  • 版權聲明
說在前面: 本文的所有示範, 都是基于Elasticsearch 6.6.0進行的, 不同的版本可能存在API發生修改、不支援的情況, 還請注意.

GET _search
           

{
    "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"
                }
            } 
        ]
    }
}
           

指定每個Shard必須在規定的時間 (也就是指定的timeout時間) 内, 将搜尋到的資料 (可能隻搜尋到了部分資料, 也可能搜尋到了全部資料) 立即傳回給用戶端, 而不是等待查詢操作完全完成後再傳回.

—— 確定在指定時間内傳回資料, 無論查詢是否完成.

ES的搜尋預設不開啟timeout, 查詢持續的時間 (latency) 将根據查詢的完整性 (completeness) 自動延遲, 可以手動指定timeout, 使用示例:

GET _search?timeout=10ms
# 可用的機關: timeout=10ms | timeout=1s | timeout=1m
           
舉例說明: ES能在1分鐘内查詢到符合條件的全部資料有2000條, 在指定

timeout=10

之後, 就會在10ms時傳回查詢到的部分結果, 此時可能隻查詢到了其中的100條資料.

(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之後的版本就隻能定義一個type.
# 搜尋一個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  
           

Elasticsearch支援通過在URI中攜帶請求參數執行搜尋.

比如要進行分頁查詢:

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的類型進行映射.

參數 使用方法

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

從所有傳回結果中的第幾條開始顯示, 預設為

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

來設定此參數.

// 查詢索引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
           

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部分 .

作者: 馬瘦風

出處: 部落格園 馬瘦風的部落格

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

本文版權歸部落客所有, 歡迎轉載, 但 [必須在文章頁面明顯位置給出原文連結], 否則部落客保留追究相關人員法律責任的權利.

繼續閱讀