Elasticsearch核心技術(三):Mapping設定

James_Shangguan發表於2021-10-29

本文從Mapping簡介、Dynamic Mapping、自定義Mapping和Mapping常用引數說明4個部分介紹Elasticsearch如何設定Mapping。

3.1 Mapping簡介

3.1.1 什麼是Mapping

Mapping類似資料庫中的表定義,主要作用如下:

  1. 定義索引下的欄位名
  2. 定義欄位的型別,比如數值型、字串型、布林型等
  3. 定義倒排索引相關的配置,比如是否索引、記錄position等

使用API獲取Mapping:
request:GET /test_index/_mapping
response:

{
  "test_index" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },

        "username" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

3.1.2 Mapping支援的資料型別

  • 核心資料型別
    • 字串型:text、keyword
    • 數值型:long、integer、short、byte、double、float、half_float、scaled_float
    • 日期型別:date
    • 布林型別:boolean
    • 二進位制型別:binary
    • 範圍型別:integer_range、float_range、long_range、double_range、data_range
  • 複雜型別
    • 陣列型別:array
    • 物件型別:object
    • 巢狀型別:nested object
  • 特殊型別
    • 地理位置:geo_point、geo_shape、
    • IP地址:IPv4、IPv6
    • 自動補全:complete
    • percolator
  • 多欄位特性:multi-fields
    • 允許對同一欄位採用不同的配置,比如分詞,常見例子如對人名實現拼音搜尋
    • 實現方式:在人名中新增一個子欄位為pinyin即可

3.2 Dynamic Mapping

3.2.1 什麼是Dynamic Mapping

  • 在文件寫入的時候,如果索引不存在,會自動建立索引
  • Dynamic Mapping的機制,使得無需手動定義Mapping,Elasticsearch會自動識別欄位的型別,從而降低使用者的使用成本
  • 但是有時候會推算的不對,例如地址位置資訊
  • 當型別如果設定不對時,會導致一些功能無法正常使用,例如Range查詢

3.2.2 型別的自動識別

ES依靠JSON文件的欄位型別來實現自動識別欄位型別,支援的型別如下:

JSON型別 ES型別
null 忽略
boolean boolean
浮點型別 float
整數 long
object object
array 由第一個非null值的型別決定
string 匹配日期格式,設定為Date(預設開啟);匹配數字,設定為float或者long(預設關閉);設定為Text,並且增加keyword子欄位

3.2.3 Dynamic的設定

當建立Index的時候,dynamic欄位可以設定成3種值:true、false、strict。

例如:

PUT movies
{
    "mapping":{
        "_doc":{
            "dynamic":"false"
        }
    }
}
true false strict
文件可索引
欄位可索引
Mapping被更新

說明:

  • 當設定成true的時候,文件可以被索引,欄位可以被搜尋,Mapping檔案可以更新。
  • 當dynamic被設定成false的時候,新增欄位的資料可以寫入ES;該資料可以被索引,但是新增欄位不可被搜尋。
  • 當設定成strict的時候,資料寫入直接報錯。

3.3 自定義Mapping

3.3.1如何自定義Mapping

自定義Mapping的一些建議

  • 可以參考API手冊,純手寫
  • 為了減少工作量,減少出錯率,可以參考以下步驟:
    1. 建立一個臨時的index,寫入一些樣本資料
    2. 通過訪問Mapping API獲得該臨時文字的動態Mapping定義
    3. 修改後,使用該配置建立索引
    4. 刪除臨時索引

3.3.2 能否更改Mapping的欄位型別

ES能否更改Mapping的欄位型別,需要分兩種情況進行分析。

1. 新增欄位
dynamic設定為true(預設值)時,一旦有新增欄位的文件寫入,Mapping也同時被更新。
dynamic設定為false時,Mapping不會被更新,更新欄位的資料無法被索引,但是資訊會出現在_source中,換言之,文件可以正常寫入,但是無法對欄位進行搜尋。
dynamic設定為strict時,文件寫入失敗。

2. 對已有欄位,一旦已經有資料寫入,就不再支援修改欄位定義。因為ES是基於Lucene實現的倒排索引,一旦生成後,就不允許修改。因為如果修改了欄位的資料型別,會導致已被索引的資料無法被搜尋。如果希望修改欄位型別,必須使用Reindex API進行重建索引。

3.4 Mapping常用引數說明

  • copy_to
    將該欄位複製到目標欄位,實現類似_all的作用;不會出現在_source中,只用來搜尋

  • index
    控制當前欄位是否索引,預設為true,即記錄索引,false不記錄,即不可搜尋。

    例如某些場景希望敏感資訊不用來做搜尋,可以將index設定為false,則不可以用來搜尋,也可以節省空間。

    index_option用於控制倒排索引記錄的內容,有4種配置:

    1. docs只記錄doc id
    2. freqs記錄doc id和term frequencies
    3. positions記錄doc id、term frequencies和term position
    4. offsets記錄doc id、term frequencies、term position和character offsets
      text型別預設配置為positions。其他預設是docs。當然記錄內容越多,佔用空間越大。
  • null_value
    當欄位遇到null值時的處理策略,預設為null,即空值,此時es會忽略該值;可以通過設定該屬性設定欄位的預設值。

更多常用引數可以參考:https://www.elastic.co/guide/en/elasticsearch/reference/7.1/mapping-params.html

相關文章