【Elasticsearch 7 探索之路】(六)初識 Mapping
上一篇主要講解什麼是 URL Search 和 Request Body Search 的語法。本篇對 Mapping 的 Dynamic Mapping 以及手動建立 Mapping 進行講解。
1.什麼是 Mapping
- Mapping 類似資料庫中的 schema 的定義,作用如下
- 定義索引中的欄位的名稱
- 定義欄位的資料型別,例如字串,數值等
- 欄位,倒排索引的相關配置,比如可以通過配置欄位是否需要被索引(Analyzed or Not Analyzed,Analyzer)
- Mapping 會把 Json 文件對映成 Lucene 所需要的扁平格式
- 一個 Mapping 屬於一個索引的 Type,在 7.0 之後版本一個索引只有一個 Type(_doc)
- 一個 Type 有一個 Mapping 定義
- 7.0 開始,不需要在 Mapping 定義中指定 type 資訊
2.常用欄位的資料型別
- 簡單型別
- Text / Keyword
- Date
- Integer / float/ double /long
- Boolean
- Ip
- 複雜型別-物件和巢狀物件
- 物件型別/巢狀型別
- 特殊型別(針對地理資訊的有特殊處理)
- geo_point & geo_shape / percolator
3.1什麼是 Dynamic Mapping
Dynamic Mapping 會自動根據文件資訊,推算出欄位的型別,使得你無需手動建立 Mapping。在寫入文件時候,而且如果索引不存在,會自動建立索引。但是有時候推算也會錯誤,例如地理位置資訊。當型別如果設定不對時,會導致一些功能無法正常執行,這點要特別注意。
下面總結 Json 型別到 Elasticsearch 型別的自動識別
3.2.Json 型別和 Elasticsearch 型別轉換對映
Json 型別 | Elasticsearch 型別 |
---|---|
字串 | 1.匹配日期格式,轉為 Date 2.數值轉為 float 或者 long,預設關閉 3.轉為 Text,並且增加 keyword |
布林值 | boolean |
浮點數 | float |
整 數 | long |
對 象 | Object |
數 組 | 由第一個非空數值的型別所決定 |
空 值 | 忽略 |
PUT mapping_test/_doc/1 { "name":"al", "age":15, "ageStr":"15", "birth":"2019-12-18", "arg":["aaa","1"], "flag":false } GET mapping_test/_mapping
3.3.能否更改 Mapping 欄位型別
- 新增欄位情況,Dynamic 設定為 true,帶有新欄位的文件寫入,Mapping 會更新。Dynamic 設定為 false,Mapping 不被更新,新增欄位不會被索引。Dynamic 設定為 Strict,帶有新欄位的文件寫入會直接報錯。
- 對已有欄位並且存在資料情況,不支援修改欄位定義,因為 ES 通過 Lucene 生成倒排索引,一旦生成就不許與修改
- 如果實在需要修改可以通過 Reindex Api 重建索引
PUT mapping_test/_mapping
{
"dynamic":"false"
}
PUT mapping_test/_doc/2
{
"name":"al",
"age":15,
"ageStr":"15",
"birth":"2019-12-18",
"arg":["aaa","1"],
"flag":false,
"addCol":"test"
}
GET mapping_test/_search
{
"query": {
"match": {
"addCol": "test"
}
}
}
當前設定 "dynamic":"false"時,新增的欄位查詢不出結果。
4.1.手動建立 Mapping
上面我們介紹了關於 Dynamic Mapping 功能,現在但我們想要手動建立一個 Mapping 該如何建立。我先看一下下面程式碼。
PUT student
{
"mappings":{
"properties": {
"firstName":{
"type":"text"
},
"lastName":{
"type":"text"
},
"password":{
"type":"text",
"index":false
}
}
}
}
PUT student/_doc/1
{
"firstName":"AA",
"lastName":"BB",
"password":"abc"
}
POST student/_search
{
"query": {
"match_phrase": {
"password": {
"query": "abc"
}
}
}
}
上面這個例子,就是一個比較簡單手動建立例子,我們通過為每一個欄位建立型別,當指定 index:false 時,ES 將不對這個欄位建立倒排索引,從上圖結果就可以看出。
4.2.Index Options
ES 有四種不同級別的 Index Options 配置
- docs 記錄 doc id
- freqs 記錄 doc id 和 term 頻次
- positions 記錄 doc id 和 term 頻次 和 term 位置
- offsets 記錄 doc id 和 term 頻次 和 term 位置和字元偏移量
Text 型別預設 positions,其他預設為 docs
4.3.copy_to
copy_to 是為瞞足一些特定搜素需求,將多個欄位 數值拷貝到目標欄位,目標欄位不會出現在 _source。在 ES7 中,copy_to 已經替代 copy_to。例如下面這個例子,把 firsetName 和 lastName 合併一起搜素。
PUT student_1
{
"mappings":{
"properties": {
"firstName":{
"type":"text",
"copy_to": "fullName"
},
"lastName":{
"type":"text",
"copy_to": "fullName"
},
"password":{
"type":"text",
"index":false
}
}
}
}
PUT student_1/_doc/1
{
"firstName":"AA",
"lastName":"BB",
"password":"abc"
}
Get student_1/_search?q=fullName:(AA BB)
5.小結
本篇主要對 Dynamic Mapping 以及手動建立 Mapping 進行講解,Dynamic Mapping 有好處也有壞處,好處我們無需定義 Mapping,壞處是推算的型別不一定正確,這點要留意。如果手動建立 Mapping 比較推薦先用 Dynamic Mapping 建立生成一個臨時索引,查詢 Mapping 定義(標題3.2 下面的結果圖)修改使用,這樣可以減少工作量和出錯的概率。
系列文章
【Elasticsearch 7 探索之路】(五)搜尋相關 Search-API
【Elasticsearch 7 探索之路】(四)Analyzer 分析
【Elasticsearch 7 探索之路】(三)倒排索引
【Elasticsearch 7 探索之路】(二)文件的 CRUD 和批量操作
【Elasticsearch 7 搜尋之路】(一)什麼是 Elasticsearch