本文從Mapping簡介、Dynamic Mapping、自定義Mapping和Mapping常用引數說明4個部分介紹Elasticsearch如何設定Mapping。
3.1 Mapping簡介
3.1.1 什麼是Mapping
Mapping類似資料庫中的表定義,主要作用如下:
- 定義索引下的欄位名
- 定義欄位的型別,比如數值型、字串型、布林型等
- 定義倒排索引相關的配置,比如是否索引、記錄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手冊,純手寫
- 為了減少工作量,減少出錯率,可以參考以下步驟:
- 建立一個臨時的index,寫入一些樣本資料
- 通過訪問Mapping API獲得該臨時文字的動態Mapping定義
- 修改後,使用該配置建立索引
- 刪除臨時索引
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種配置:
- docs只記錄doc id
- freqs記錄doc id和term frequencies
- positions記錄doc id、term frequencies和term position
- 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