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

本文從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會忽略該值;可以通過設定該屬性設定欄位的默認值。

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