Elasticsearch的映射(mapping)是什麼? 在創建索引時, 如何對不同的數據類型進行特殊的配置與操作? 映射(mapping)有哪些組成部分? 如何配置和更新mapping? 這篇文章通通告訴你. ...
目錄
1 映射的相關概念
1.1 什麼是映射
(1) 映射(mapping): 定義index的元數據, 指定要索引並存儲的文檔的欄位類型.
也就是說映射決定了Elasticsearch在建立倒排索引、進行檢索時對文檔採取的相關策略, 如數字類型、日期類型、文本類型等等.
需要註意的是: 檢索時用到的分析策略, 要和建立索引時的分析策略相同, 否則將導致數據不准確.
(2) ES對不同的類型有不同的存儲和檢索策略.
① 比如: 對full text型的數據類型(如text), 在索引時, 會經過各類處理 (包括分詞、normalization(時態轉換、同義詞轉換、大小寫轉換)等處理), 才會建立到索引數據中.
② 再比如: 對exact value(如date), 在索引的分詞階段, 會將整個value作為一個關鍵詞建立到倒排索引中.
1.2 映射的組成
每個index都有一 (至多) 個type, 每個type對應一個mapping.
在Elasticsearch 6.X版本開始, 1個index只能有1個type.
每個mapping都由下述部分組成:
① 元欄位:
_index
、_type
、_id
和_source
.
② field/properties(欄位或屬性): 同一index中, 同名的field的映射配置必須相同a) 因為index是根據
_type
元欄位來區分type的, 也就是存儲的每個文檔中都有_type
等元欄位, 如果相同名稱的field的映射(_type
欄位的值)不同, Elasticsearch在解析時就會出現衝突.b) 這些參數可以例外:
copy_to、dynamic、enabled、ignore_above、include_in_all
.
關於type的處理方法, 可以參考博客: ES XX - Elasticsearch對type的處理(type的底層結構).
1.3 元欄位
每個文檔都有與之關聯的元數據 —— ES內部為所有的文檔配備的field, 都是以下劃線_
開頭的內置欄位.
具體的內容請參考博文 ES XX - Elasticsearch的元欄位 中詳細講解.
1.4 欄位的類型
Elasticsearch中每個field都對應一至多個數據類型.
詳細的內容請參考博文 ES XX - Elasticsearch中欄位的類型 中詳細講解.
2 如何配置mapping
2.1 創建mapping
(1) 必讀說明:
① 創建mapping時, 可以指定每個field是否需要:
索 引:
"index": true
—— 預設配置
不索引:"index": false
② mapping root object
:
每個type對應的mapping的JSON串, 包括properties, metadata(_id, _source, _type) , settings(analyzer) , 其他settings(如include_in_all)
(2) 創建mapping的示例:
需求: 創建名為website的索引, 包含一個user類型. user類型中禁用元欄位_all
.
PUT website
{
"mappings": {
"user": { // 這就是一個root object
"_all": { "enabled": false }, // 禁用_all欄位
"properties": {
"user_id": { "type": "text" },
"name": {
"type": "text",
"analyzer": "english"
},
"age": { "type": "integer" },
"sex": { "type": "keyword" },
"birthday": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"address": {
"type": "text",
"index": false // 不分詞
}
}
}
}
}
(3) 過期提示說明 —— 這裡使用的是Elasticsearch 6.6.10版本:
① 是否索引的API已經做了修改, 若使用"analyzed" | "not_analyzed" | "yes" | "no"等, 將拋出如下警告:
#! Deprecation: Expected a boolean [true/false] for property [index] but got [not_analyzed] #! Deprecation: Expected a boolean [true/false] for property [index] but got [no]
②
_all
元欄位也將在7.0版本中移除, 它建議我們使用copy_to
定製自己的all field
:#! Deprecation: [_all] is deprecated in 6.0+ and will be removed in 7.0. As a replacement, you can use [copy_to] on mapping fields to create your own catch all field.
2.2 更新mapping
(1) 必讀說明:
映射一旦創建完成, 就不允許修改:
—— Elasticsearch對文檔的分析、存儲、檢索等過程, 都是嚴格按照mapping中的配置進行的. 如果允許後期修改mapping, 在檢索時對索引的處理將存在不一致的情況, 導致數據檢索行為不准確.
只能在創建index的時候手動配置mapping, 或者新增field mapping, 但是不能update field mapping.
(2) 更新mapping出現異常:
修改已經創建好的mapping
PUT website { "mappings": { "user": { "properties": { "author_id": { "type": "text" } } } } }
拋出如下錯誤 —— 索引已經存在的異常:
{ "error": { "root_cause": [ { "type": "resource_already_exists_exception", "reason": "index [website/mVYk4-a7RMOZbkcCp2avfw] already exists", "index_uuid": "mVYk4-a7RMOZbkcCp2avfw", "index": "website" } ], "type": "resource_already_exists_exception", "reason": "index [website/mVYk4-a7RMOZbkcCp2avfw] already exists", "index_uuid": "mVYk4-a7RMOZbkcCp2avfw", "index": "website" }, "status": 400 }
(3) 向mapping中添加新type:
向已有mapping中添加欄位及其映射信息:
PUT website/_mapping/user // 修改user類型的_mapping, 註意API的順序 { "properties": { "new_field": { "type": "text", "index": false } } }
2.3 查看mapping
(1) 查看mapping的API:
GET website/_mapping
(2) 查看的結果信息如下:
{
"website" : {
"mappings" : {
"user" : {
"_all" : {
"enabled" : false // 禁用元欄位_all
},
"properties" : {
"address" : {
"type" : "text",
"index" : false // 不索引
},
"age" : {
"type" : "integer"
},
"birthday" : {
"type" : "date"
},
"name" : {
"type" : "text",
"analyzer" : "english"
},
"new_field" : { // 後期添加的新欄位
"type" : "text",
"index" : false // 不索引
},
"sex" : {
"type" : "keyword"
},
"user_id" : {
"type" : "text"
}
}
}
}
}
}
版權聲明
作者: ma_shoufeng(馬瘦風)
出處: 博客園 馬瘦風的博客
您的支持是對博主的極大鼓勵, 感謝您的閱讀.
本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 併在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.