elastic search 原理介紹

【唐】三三發表於2024-11-15

Elasticsearch 原理與實現

文件欄位

1 欄位索引

預設情況下,只有text型別的欄位會儲存文件ID、詞頻、詞序以外,其餘型別欄位均只儲存文件ID。使用者可以在對映欄位時透過index_option引數來設定,它的可選值為 docs、freqs、positions、offsets,編入索引l的資訊依次增加,具體含義如下:

docs:只有文件ID會被編入索引;
freqs:文件ID、詞頻會被編入索引;
positions:文件ID、詞頻和詞序會被編入索引;
offsets:文件ID、詞頻、詞序和偏移量都會被編入索引。

由此也可以看出,儘管在預設情況下所有的欄位都會被索引,但是這些欄位的原始值是不會被編入索引中的。這意味著使用者可以透過某一欄位的詞項檢索到文件,但並不能直接取到這個欄位的原始值。因為欄位的索引最多隻包含上述四項內容,並不包含欄位原始值。

2 欄位儲存

欄位原始值 _source

索引提供了一個_source的欄位用於儲存整個文件的原始值。_source欄位有一個特性,那就是這個欄位在預設情況下是不會被索引的,但是每個查詢預設都會帶著_source欄位返回。如果確定不需要使用_source欄位儲存源文件,也可以在建立索引透過對映型別的_source引數將其關閉

PUT /users
{
  "mappings":{
  _source":{
    "enabled":false
    } 
  }
}

於設定對映關係,_source則是控制_source欄位的開關。不推薦關閉_source欄位通常,因為_source欄位與以下一些功能相關聯:

  • 使用update、update_by_query更新文件,使用reindex重新索引文件;

  • 執行時高亮檢索結果;

  • 在不同的Elasticsearch例項間重新索引|文件;

  • 使用源文件對檢索和聚集做debug。

關閉_source欄位後,上述功能也將無法使用,所以在考慮關閉_source欄位時要權衡清楚。通常關閉_source欄位的主要原因是出於節省儲存空間,Elastic官方建議如果單純只是考慮節省儲存空間可以透過修改index.codec提高壓縮效率.

文件值 doc_values

doc_values 儲存的並非原始文件內容,而是針對文件中那些可以被用於排序、聚合、指令碼操作等的欄位(列),將其值以一種列式儲存的結構進行儲存,便於快速的資料讀取和相應的計算操作。它實際上是 Elasticsearch 為了提升查詢效能,對特定型別資料進行的一種最佳化儲存方式。例如對於數值型欄位(如文章的字數統計數值)、日期型欄位(如釋出時間)、布林型欄位等,會把這些欄位的值按照 doc_values 的方式儲存起來,方便後續快速查詢和計算分析。

所有非text型別的欄位都支援文件值機制,並且都是開啟的

fielddata

文件值doc_values機制的資料結構儲存在硬碟中,而fielddata機制則是在記憶體中構建資料結構,所以使用fielddata機制有可能導致JVM記憶體溢位。不僅如此,fielddata機制儲存的也不是欄位原始值,而是透過遍歷倒排索引建立文件與它所包含詞項的對應關係。

具體來說,Elasticsearch會在首次對欄位進行聚集、排序等請求時,遍歷所有倒排索引並在記憶體中構建起文件與詞項之間的對應關係。在預設情況下,text欄位的fielddata機制是關閉的,可以透過在對映欄位時修改fielddata引數開啟。

在開啟fielddata機制前要考慮清楚,因為這種機制顯然非常消耗資源,而且使用text型別欄位做聚集、排序也往往不是合理的需求。即便是真的有這樣的需求,也可以透過欄位多資料型別來開啟文件值機制,而儘量不要使用fielddata機制

  • 文字欄位聚合操作:對於文字型別的欄位,若要進行諸如分組統計不同詞彙出現的頻次、按關鍵詞進行分組等聚合分析時,就需要藉助fielddata。比如在一個電商產品索引中,對 “商品評價” 欄位進行分析,統計使用者提及最多的評價關鍵詞,這時fielddata會幫助解析 “商品評價” 裡的文字內容並用於聚合計算。
  • 文字欄位排序操作:當要依據文字欄位裡的詞項順序等進行排序時,比如按照使用者搜尋關鍵詞在文件中的匹配順序來對搜尋結果排序,fielddata能提供相應的資料支援,讓這種基於文字內容詞項的排序得以實現。
  • 指令碼中基於文字詞項的操作:在自定義指令碼里,如果需要對文字欄位的詞項進行邏輯判斷、數值計算等操作(比如判斷某個關鍵詞是否在文件的文字欄位中出現,出現次數達到一定數值就進行相應處理),fielddata裡儲存的文字詞項相關資料就可以被指令碼訪問和使用。

相關文章