以下為官網原文 鏈接
Why are mapping types being removed?edit
Initially, we spoke about an “index” being similar to a “database” in an SQL database, and a “type” being equivalent to a “table”.
This was a bad analogy that led to incorrect assumptions. In an SQL database, tables are independent of each other. The columns in one table have no bearing on columns with the same name in another table. This is not the case for fields in a mapping type.
In an Elasticsearch index, fields that have the same name in different mapping types are backed by the same Lucene field internally. In other words, using the example above, the user_name field in the user type is stored in exactly the same field as the user_name field in the tweet type, and both user_name fields must have the same mapping (definition) in both types.
This can lead to frustration when, for example, you want deleted to be a date field in one type and a boolean field in another type in the same index.
On top of that, storing different entities that have few or no fields in common in the same index leads to sparse data and interferes with Lucene’s ability to compress documents efficiently.
For these reasons, we have decided to remove the concept of mapping types from Elasticsearch.
Elasticsearch7.X為什么移除類型(type)
在Elasticsearch7.0.0及以后版本不再接受_default_ 映射。在6.x里創建的索引依然像在Elasticsearch6.X之前一樣起作用。Types在7.0的API里是被舍棄的,在創建索引,設置映射,獲取映射,設置模板,獲取模板,獲取字段映射API有着不兼容的改變。
index、type的初衷
之前es將index、type類比於關系型數據庫(例如mysql)中database、table,這么考慮的目的是“方便管理數據之間的關系”。
【本來為了方便管理數據之間的關系,類比database-table 設計了index-type模型】
什么是類型(type)?
從Elasticsearch的第一個發布版本以來,每一個文檔都被存儲在一個單獨的索引里,並被賦予了一個type,一個映射類型代表着一個被索引的文檔或實體的類型,例如,一個twitter索引可能有一個user類型和tweet類型。
每種映射類型都有他自己的字段,所以user類型可能有一個full_name字段,一個user_name字段和一個email字段,而一個tweet類型可能有一個content字段,一個tweet_at字段,和user類型一樣一個user_name字段。
每一個文檔類型都有一個_type元字段來存儲type名稱,並且根據URL里指定的類型名稱,查詢(搜索)被限定在一個或多個類型(type)里:
GET twitter/user,tweet/_search { "query": { "match": { "user_name": "kimchy" } } }
_type字段用來和文檔的_id字段聯合生成_uid字段,所以有着相同_id的不同類型的文檔可以存在同一個索引里。類型也用來建立文檔間的父子關系,所以question類型的文檔可能是anser類型文檔的父文檔。
1、我們經常把二維數據庫與ES作類比的方式是不正確的假設。把“index”類比為數據庫,“type”類比為表。具體原因是,數據庫的表是物理獨立的,一個表的列跟另外一張表相同名稱的列沒有關系,而ES中並非如此,不同type映射類型中具有相同名稱的字段在內部由相同的Lucene字段支持。
2、當您想要索引一個deleted字段在不同的type中數據類型不一樣。一個類型中為日期字段,另外一個類型中為布爾字段時,這可能會導致ES的存儲失敗,因為這影響了ES的初衷設計。
3、另外,在一個index中建立很多實體,type,沒有相同的字段,會導致數據稀疏,最終結果是干擾了Lucene有效壓縮文檔的能力,說白了就是影響ES的存儲、檢索效率。
為什么現在要移除type?
2.1 在關系型數據庫中table是獨立的(獨立存儲),但es中同一個index中不同type是存儲在同一個索引中的(lucene的索引文件),因此不同type中相同名字的字段的定義(mapping)必須一致。
2.2 不同類型的“記錄”存儲在同一個index中,會影響lucene的壓縮性能。
【總結:
es基於Lucene的索引文件擴展type結構,也受限制與同一個index里的不同的type存儲再同樣一個索引文件里
這樣不同type里的相同名字的field mapping必須一致,事實上上數據庫中的不同的table表是獨立存儲的,不同的table里的字段是 獨立設計的
於是type的用途非常有限,比如下面的替換方案】
替換策略
3.1 一個index只存儲一種類型的“記錄”
這種方案的優點:
a)lucene索引中數據比較整齊(相對於稀疏),利於lucene進行壓縮。
b)文本相關性打分更加精確(tf、idf,考慮idf中命中文檔總數)
3.2 用一個字段來存儲type
如果有很多規模比較小的數據表需要建立索引,可以考慮放到同一個index中,每條記錄添加一個type字段進行區分。
這種方案的優點:
a)es集群對分片數量有限制,這種方案可以減少index的數量。
方案1:去掉type,全部使用獨立的index;問題:index太多影響es集群分片效果。
方案2:如果數據量不大,可以把一個index下不同的type 合並成一個index;通過一個field字段比如就叫 _type 來區分之前的index-type
遷移方案
之前一個index上有多個type,如何遷移到3.1、3.2方案?
- 先針對實際情況創建新的index,[3.1方案]有多少個type就需要創建多少個新的index,[3.2方案]只需要創建一個新的index。
- 調用_reindex將之前index上的數據同步到新的索引上;第二個方案通過_reindex 配合腳本區分不同的type字段
Elasticsearch 移除 type 之后的新姿勢
隨着 7.0 版本的即將發布,type
的移除也是越來越近了,在 6.0 的時候,已經默認只能支持一個索引一個 type 了,7.0 版本新增了一個參數 include_type_name
,即讓所有的 API 是 type 相關的,這個參數在 7.0 默認是 true
,不過在 8.0 的時候,會默認改成 false
,也就是不包含 type 信息了,這個是 type 用於移除的一個開關。