參考:
https://bayescafe.com/database/elasticsearch-using-index-or-type.html
https://www.cnblogs.com/huangfox/p/9460361.html
1. type理解
1.1 Type 是什么
使用 type 允許我們在一個 index 里存儲多種類型的數據,這樣就可以減少 index 的數量了。在使用時,向每個文檔加入 _type 字段,在指定 type 搜索時就會被用於過濾。使用 type 的一個好處是,搜索一個 index 下的多個 type,和只搜索一個 type 相比沒有額外的開銷 —— 需要合並結果的分片數量是一樣的。
但是,這也是有限制的:
- 不同 type 里的字段需要保持一致。例如,一個 index 下的不同 type 里有兩個名字相同的字段,他們的類型(string, date 等等)和配置也必須相同。
- 只在某個 type 里存在的字段,在其他沒有該字段的 type 中也會消耗資源。這是 Lucene Index 帶來的常見問題:它不喜歡稀疏。由於連續文檔之間的差異太大,稀疏的 posting list 的壓縮效率不高。這個問題在 doc value 上更為嚴重:為了提高速度,doc value 通常會為每個文檔預留一個固定大小的空間,以便文檔可以被高速檢索。這意味着,如果 Lucene 確定它需要一個字節來存儲某個數字類型的字段,它同樣會給沒有這個字段的文檔預留一個字節。未來版本的 ES 會在這方面做一些改進,但是我仍然建議你在建模的時候盡量避免稀疏。[1]
- 得分是由 index 內的統計數據來決定的。也就是說,一個 type 中的文檔會影響另一個 type 中的文檔的得分。
這意味着,只有同一個 index 的中的 type 都有類似的映射 (mapping) 時,才應該使用 type。否則,使用多個 type 可能比使用多個 index 消耗的資源更多。
1.2 我應該用哪個
這是個困難的問題,它的答案取決於你用的硬件、數據和用例。首先你要明白 type 是有用的,因為它能減少 ES 需要管理的 Lucene Index 的數量。但是也有另外一種方式可以減少這個數量:創建 index 的時候讓它的分片少一些。例如,與其在一個 index 里塞上 5 個 type,不如創建 5 個只有一個分片的 index。
在你做決定的時候可以問自己下面幾個問題:
- 你需要使用父子文檔嗎?如果需要,只能在一個 index 里建立多個 type。
- 你的文檔的映射是否相似?如果不相似,使用多個 index。
- 如果你的每個 type 都有足夠多的文檔,Lucene Index 的開銷可以被分攤掉,你就可以安全的使用多個 index 了。如果有必要的話,可以把分片數量設小一點。
- 如果文檔不夠多,你可以考慮把文檔放進一個 index 里的多個 type 里,甚至放進一個 type 里。
2. 移除映射類型的計划
修改這種模型將會是一個比較大的變化,因此 Elasticsearch 也在盡量少影響用戶的前提下,做了一些功能的規划:
ElasticSearch 5.6.0
在索引上設置 index.mapping.single_type: true來啟用單個類型單個索引,6.0 版本后會進一步增強
從 5.6.0 版本開始,使用 join 字段來替換 父子關系
Elasticsearch 6.x
5.x 創建的索引在 6.x 版中將繼續可以使用
6.x 中將只允許單個類型單個索引, 比較推薦的類型名字為 _doc, 這樣可以讓索引的API具備相同的路徑 PUT {index}/_doc/{id} 和 POST {index}/_doc
_type 字段名稱將不再與 _id 字段合並生成 _uid字段, _uid 字段將作為 _id 的別名。
新的索引將不再支持父子關系,應該采用 join 字段類進行替代
_default 映射類型將不推薦使用
Elasticsearch 7.x
URL 中的 type 參數做變為可選。例如,所以文檔將不再需要 type。指定 id 的 URL 將變為 PUT {index}/_doc/{id}, 自動生成 id 的 URL 為:POST {index}/_doc
GET | PUT _mapping API 支持查詢字符串參數(include_type_name),該參數指示主體是否應包含類型名稱。 它默認為 true, 7.x 沒有顯式類型的索引將使用虛擬類型名稱 _doc。
_default 映射類型將被移除
Elasticsearch 8.x
參數 type 在 URL 中將不再被支持
參數include_type_name 默認seize為 false
