ES Search流程 與GET/MGET

ES的讀取分爲GET和Search兩種操作,這兩種讀取操作有較大的差異,本章我們主要分析下GET/MGET讀取操作。

GET/MGET

GET/MGET必須指定三元組:_index、_type、_id(http://127.0.0.1:9200/_index/_type/_id),也就是說,根據文檔id從正排索引中獲取內容。GET操作只能對單個文檔進行處理,MGET是對GET的進一步封裝(封裝了多個GET請求),由_index,_type,_id三元組來確定唯一文檔。

http://127.0.0.1:9200/_index/_type/_id -> 相應的文檔

GET請求流程如下:

(1)客戶端向NODE1發送讀請求(此時NODE1作爲協調節點)

(2)NODE1是同文檔ID來確定文檔屬於分片0,通過集羣狀態中的內容路由表信息獲取分片0有三個副本數據,位於三個節點中,此時它可以通過將請求發送到任意節點,圖上所示是將請求發送到NODE2。

(3)NODE2將文檔返回給NODE1,NODE1將文檔返回給客戶端(因爲只是獲取單個數據信息,不會涉及協調節點的聚合等操作)

注:GET/MGET詳細的設計原理可以參考:ES GET/MGET 設計理解

注:ElasticSearch中同時保存了正排索引和倒排索引,對該知識不清楚的可以參考:

深入理解正排索引與倒排索引(設計思想和數據結構)

🤔思考:那麼對於一些複雜的操作,而且不知道文檔ID,應該如何進行查詢?

這也是我們下面所講的Search操作。

Search操作

ES中的數據可以分爲兩類:

  • 精確值:比如日期和用戶id,ip等信息
  • 全文:☞文章內容,比如一跳日誌,或者郵件的內容。

這兩種類型的數據在查詢的時候也是不相同的:對精確值的比較是二進制,查詢要麼匹配,要麼不匹配;全文內容的查詢無法給出“有”還是“沒有”的結果,它只能找到結果是“看起來像”你要查詢的東西,因此把查詢結果按相似度排序,評分越高,相似度越大

大致流程如下:

(1)客戶端發送請求協調節點

(2)因爲查詢的時候不知道文檔位於哪個分片,因此索引的所有分片(某個副本)都要參與搜索,調節點計算出索引的分片位置進行搜索(也就是查詢階段)。

(3)協調節點進行結果合併,根據獲取到返回的文檔ID,再次訪問並獲取文檔內容。比如:有5個分片,查詢前10個匹配度最高的文檔,那麼每個分片都能查詢出分片的TOP10,協調節點將5*10=50的結果再次排序,返回最紅TOP10的結果給客戶。

ES對數據建立索引和執行搜索的原理如下圖:

建立索引

如果是全文數據,則對文本內容進行分析,這項工作在ES中由分析器實現。分析器實現如下:

(1)字符過濾器。主要針對字符串進行預處理,比如:去掉HTML,將&轉換爲and等

(2)分詞器(Tokenizer)。將字符串分割爲單個詞條,例如,根據空格和標點符號分割(ES內置了很多分詞器,也可以自定義),輸出的詞條稱爲詞元(Token)

(3)Token過濾器(分詞過濾器)。這些分詞過濾器將一個詞元作爲輸入,根據需要進行修改,添加或者是刪除。最爲有用的和常用的分詞過濾器是小寫分詞過濾器(將輸入的分詞變爲小寫,搜索詞條“nosql”的時候,可以發現關於“NoSql”的聚合),分詞過濾器還可以刪除像“and”等常用詞,也可以將“tools”作爲“technologies”的同義詞進行添加

(4)建立分詞索引:當分詞經歷了零個或者多個分詞過濾器,他們將被髮送到Lucene進行文檔的索引。這些分詞組將組成倒排索引

注:在搜索在索引中執行之前,根據所使用的查詢類型,分析統一可以運用到搜索的文本

搜索建立

搜索調用Lucene 完成,如果是全文搜索,則:

(1)對檢索字段使用建立索引時相同的分析器進行分析,產生Token列表;

(2)根據查詢語句的語法規則轉換成一個語法樹

(3)查找符合語法樹的文檔

(4)對匹配到的文檔列表進行相關性評分,評分策略一般使用TF/IDF

(5)根據評分結果進行排序

整個搜索過程分爲兩個步驟:query 和 fetch ,整體流程如下圖所示:

 

query階段

在初始查詢階段,查詢會廣播到索引中每一個分片副本(主分片或副分片)。每個分片在本地執行搜索並構建一個匹配文檔的優先隊列(優先隊列是一個由topN匹配文檔的有序列表。優先隊列大小爲分頁參數from+size)。


 

 

(1)客戶端發送search請求到NODE3。

(2)Node3將查詢請求轉發到索引的每個主分片或者副分片

(3)每個分片在本地執行查詢,並使用本地的Term/Document Frequency信息進行打分,添加結果到大小爲from + size的本地有序優先隊列中。

(4)每個分片返回個自己優先隊列中所有文檔的ID和排序值給協調節點,協調節點合併這些值到自己的優先隊列中,產生一個全局排序後的列表

注:查詢階段並不會對搜索請求的內容進行解析,無論搜索什麼內容,只看本次搜索需要命重哪些shard,然後針對每個特定shard選擇一個複雜,轉發搜索請求

Fetch 階段

Query階段知道了要取哪些數據,但是並沒有獲取具體的數據,這個步驟在Fetch階段實現

Fetch階段如圖:

Fetch階段由以下步驟完成:

(1)協調節點向相關NODE發送GET請求。

(2)分片所在節點向協調節點返回數據。

(3)協調節點等待所有文檔被取得,然後返回給客戶端

注:聚合時在ES中實現的,而非Lucene

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章