在Elasticsearch 7.0.0或更高版本中建立的索引再也不接受
_default_
映射,索引在6.x中建立將繼續在Elasticsearch 6.x中運行,類型在api 7.0中是不受支持的,它會中斷對索引建立、put映射、get映射、put模板、get模板和get字段映射API的更改。
自從第一次發佈Elasticsearch以來,每一個文檔都存儲在一個索引中,並分配了一個映射類型,映射類型用於表示被索引的文檔或實體的類型,例如twitter
索引可能具備user
類型和tweet
類型。數據庫
每一個映射類型均可以有本身的字段,所以user
類型能夠有full_name
字段、user_name
字段和email
字段,而tweet
類型能夠有content
字段、tweeted_at
字段,和user
類型同樣,還有user_name
字段。segmentfault
每一個文檔都有一個包含類型名稱的_type
元字段,經過在URL中指定類型名稱,能夠將搜索限制爲一個或多個類型:api
GET twitter/user,tweet/_search { "query": { "match": { "user_name": "kimchy" } } }
_type
字段與文檔的_id
相結合生成_uid
字段,所以具備相同_id
的不一樣類型的文檔能夠存在於一個索引中。app
還使用映射類型在文檔之間創建父子關係,所以類型爲question
的文檔能夠是類型爲answer
的文檔的父文檔。ui
最初,討論了「索引」相似於SQL數據庫中的「數據庫」,以及「類型」等價於「表」。code
這是一個錯誤的類比,致使了錯誤的假設,在SQL數據庫中,表是相互獨立的,一個表中的列與另外一個表中具備相同名稱的列沒有關係,這與映射類型中的字段不一樣。繼承
在Elasticsearch索引中,不一樣映射類型中具備相同名稱的字段在內部由相同的Lucene字段支持,換句話說,使用上面的示例,user
類型中的user_name
字段存儲在與tweet
類型中的user_name
字段徹底相同的字段中,並且兩個user_name
字段在這兩種類型中必須具備相同的映射(定義)。索引
例如,當你想要刪除一個類型中的date
字段和同一個索引中的另外一個類型中的boolean
字段時,這可能會致使失敗。ip
最重要的是,存儲在同一索引中具備不多或沒有共同字段的不一樣實體會致使數據稀疏,並影響Lucene有效壓縮文檔的能力。文檔
基於這些緣由,決定將映射類型的概念從Elasticsearch中移除。
第一種選擇是爲每一個文檔類型都有一個索引,你能夠將tweets
存儲爲tweets
和user
索引,而不是將tweets
和users
存儲在單個twitter
索引中,索引之間是徹底獨立的,所以索引之間不存在字段類型的衝突。
這種方法有兩個好處:
每一個索引均可以根據它將包含的文檔數量適當調整大小:你能夠爲users
使用較少的主碎片,而爲tweet
使用較多的主碎片。
固然,集羣中能夠存在多少主碎片是有限制的,所以你可能不但願爲了一個只有幾千個文檔的集合而浪費整個碎片,在本例中,你能夠實現本身的自定義類型字段,其工做方式與舊的_type
相似。
讓咱們以上面的user
/tweet
爲例,最初,工做流應該是這樣的:
PUT twitter { "mappings": { "user": { "properties": { "name": { "type": "text" }, "user_name": { "type": "keyword" }, "email": { "type": "keyword" } } }, "tweet": { "properties": { "content": { "type": "text" }, "user_name": { "type": "keyword" }, "tweeted_at": { "type": "date" } } } } } PUT twitter/user/kimchy { "name": "Shay Banon", "user_name": "kimchy", "email": "shay@kimchy.com" } PUT twitter/tweet/1 { "user_name": "kimchy", "tweeted_at": "2017-10-24T09:00:00Z", "content": "Types are going away" } GET twitter/tweet/_search { "query": { "match": { "user_name": "kimchy" } } }
你能夠經過添加自定義類型字段來實現相同的功能,以下所示:
PUT twitter { "mappings": { "_doc": { "properties": { "type": { "type": "keyword" }, "name": { "type": "text" }, "user_name": { "type": "keyword" }, "email": { "type": "keyword" }, "content": { "type": "text" }, "tweeted_at": { "type": "date" } } } } } PUT twitter/_doc/user-kimchy { "type": "user", "name": "Shay Banon", "user_name": "kimchy", "email": "shay@kimchy.com" } PUT twitter/_doc/tweet-1 { "type": "tweet", "user_name": "kimchy", "tweeted_at": "2017-10-24T09:00:00Z", "content": "Types are going away" } GET twitter/_search { "query": { "bool": { "must": { "match": { "user_name": "kimchy" } }, "filter": { "match": { "type": "tweet" } } } } }
type
字段替代了隱式_type
字段。之前,父—子關係表示爲將一個映射類型表示爲父,將一個或多個其餘映射類型表示爲子,沒有類型,咱們就不能再使用這種語法,除了表示文檔之間關係的方式已更改成使用新的join
字段外,父—子特性將繼續像之前同樣工做。
對於用戶來講,這是一個巨大的變化,因此已經嘗試讓它儘量地不那麼痛苦,更改將按以下方式進行:
Elasticsearch 5.6.0
index.mapping.single_type: true
將啓用在6.0中強制執行的單類型/索引行爲。join
字段替換。Elasticsearch 6.x
_doc
,所以索引API具備與7.0中相同的路徑:PUT {index}/_doc/{id} and POST {index}/_doc
。_type
名稱不能再與_id
組合以造成_uid
字段,_uid
字段已成爲_id
字段的別名。join
字段。_default_
映射類型已棄用。include_type_name
),該參數指示請求和響應是否應該包含類型名稱。它默認爲true
,應該設置爲一個顯式值,以便準備升級到7.0,未設置include_type_name
將致使一個棄用警告,沒有顯式類型的索引將使用虛擬類型名稱_doc
。Elasticsearch 7.x
type
,對於顯式id,新的索引API是PUT {index}/_doc/{id}
,對於自動生成的id則是POST {index}/_doc
,注意,在7.0中,_doc
是路徑的一個永久部分,它表示端點名稱,而不是文檔類型。include_type_name
參數默認爲false
,徹底設置該參數將致使一個棄用警告。_default_
映射類型。Elasticsearch 8.x
include_type_name
參數。Reindex API可用於將多類型索引轉換爲單類型索引,下面的例子能夠在Elasticsearch 5.6或Elasticsearch 6.x中使用,在6.x,不須要指定index.mapping.single_type
做爲默認值。
第一個示例將twitter
索引拆分爲tweets
索引和users
索引:
PUT users { "settings": { "index.mapping.single_type": true }, "mappings": { "_doc": { "properties": { "name": { "type": "text" }, "user_name": { "type": "keyword" }, "email": { "type": "keyword" } } } } } PUT tweets { "settings": { "index.mapping.single_type": true }, "mappings": { "_doc": { "properties": { "content": { "type": "text" }, "user_name": { "type": "keyword" }, "tweeted_at": { "type": "date" } } } } } POST _reindex { "source": { "index": "twitter", "type": "user" }, "dest": { "index": "users" } } POST _reindex { "source": { "index": "twitter", "type": "tweet" }, "dest": { "index": "tweets" } }
下一個示例添加一個自定義類型字段,並將其設置爲原始_type
的值,它還將類型添加到_id
中,以防有任何不一樣類型的文檔具備衝突的id
:
PUT new_twitter { "mappings": { "_doc": { "properties": { "type": { "type": "keyword" }, "name": { "type": "text" }, "user_name": { "type": "keyword" }, "email": { "type": "keyword" }, "content": { "type": "text" }, "tweeted_at": { "type": "date" } } } } } POST _reindex { "source": { "index": "twitter" }, "dest": { "index": "new_twitter" }, "script": { "source": """ ctx._source.type = ctx._type; ctx._id = ctx._type + '-' + ctx._id; ctx._type = '_doc'; """ } }
在Elasticsearch 7.0中,每一個API都支持無類型請求,指定類型將產生一個棄用警告。
即便目標索引包含自定義類型,無類型API也能夠工做,例如,若是索引具備自定義類型名稱my_type
,則可使用無類型index
調用向其添加文檔,並使用無類型get
調用加載文檔。
索引建立、索引模板和映射API支持一個新的include_type_name
URL參數,該參數指定請求和響應中的映射定義是否應該包含類型名稱,版本6.8中的參數默認爲true
,以匹配在映射中使用類型名稱的7.0以前的行爲,它在7.0版本中默認爲false
,將在8.0版本中刪除。
它應該在6.8中明確設置,以便準備升級到7.0,爲了不6.8中的棄用警告,能夠將參數設置爲true
或false
,在7.0中,設置include_type_name
將致使一個棄用警告。
查看一些與Elasticsearch交互的例子,這個選項設置爲false
:
PUT index?include_type_name=false { "mappings": { "properties": { "foo": { "type": "keyword" } } } }
mappings
鍵下,沒有類型名稱。PUT index/_mappings?include_type_name=false { "properties": { "bar": { "type": "text" } } }
mappings
鍵下,沒有類型名稱。GET index/_mappings?include_type_name=false
上面的調用返回:
{ "index": { "mappings": { "properties": { "foo": { "type": "keyword" }, "bar": { "type": "text" } } } } }
mappings
鍵下,沒有類型名稱。在7.0中,必須使用{index}/_doc
路徑調用索引API,以便自動生成_id
,使用顯式id
調用{index}/_doc/{id}
。
PUT index/_doc/1 { "foo": "baz" }
{ "_index": "index", "_id": "1", "_type": "_doc", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 }
相似地,get
和delete
API使用路徑{index}/_doc/{id}
:
GET index/_doc/1
在7.0中,_doc
表示端點名稱,而不是文檔類型,_doc
組件是文檔index
、get
和delete
API路徑的永久部分,在8.0中不會被刪除。
對於同時包含類型和端點名(如_update
)的API路徑,在7.0中端點將當即跟隨索引名:
POST index/_update/1 { "doc" : { "foo" : "qux" } } GET /index/_source/1
類型也不該該再出如今請求體中,下面的bulk
索引示例省略了URL和單個批量命令中的類型:
POST _bulk { "index" : { "_index" : "index", "_id" : "3" } } { "foo" : "baz" } { "index" : { "_index" : "index", "_id" : "4" } } { "foo" : "qux" }
在調用諸如_search
、_msearch
或_explain
之類的搜索API時,URL中不該該包含類型,此外,_type
字段不該該用於查詢、聚合或腳本。
文檔和搜索API將繼續在響應中返回_type
鍵,以免中斷響應解析,然而,鍵被認爲是不同意的,不該該再被引用,類型將在8.0中從響應中徹底刪除。
注意,當使用廢棄的類型化API時,索引的映射類型將做爲正常返回,可是無類型API將在響應中返回虛擬類型_doc
,例如,下面的無類型get
調用老是返回_doc
做爲類型,即便映射有一個像my_type
這樣的自定義類型名:
PUT index/my_type/1 { "foo": "baz" } GET index/_doc/1
{ "_index" : "index", "_type" : "_doc", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found": true, "_source" : { "foo" : "baz" } }
建議經過將include_type_name
設置爲false
來從新添加索引模板,使其無類型,在底層,無類型模板在建立索引時將使用虛擬類型_doc
。
若是將無類型模板用於類型化索引建立調用,或者將類型化模板用於無類型索引建立調用,則仍將應用模板,但索引建立調用將決定是否應該有類型。例如在下面的示例中,index-1-01
將具備一個類型,儘管它匹配一個沒有類型的模板,而index-2-01
將具備無類型,儘管它匹配一個定義了類型的模板,index-1-01
和index-2-01
都將從匹配的模板中繼承foo
字段。
PUT _template/template1 { "index_patterns":[ "index-1-*" ], "mappings": { "properties": { "foo": { "type": "keyword" } } } } PUT _template/template2?include_type_name=true { "index_patterns":[ "index-2-*" ], "mappings": { "type": { "properties": { "foo": { "type": "keyword" } } } } } PUT index-1-01?include_type_name=true { "mappings": { "type": { "properties": { "bar": { "type": "long" } } } } } PUT index-2-01 { "mappings": { "properties": { "bar": { "type": "long" } } } }
在隱式索引建立的狀況下,由於文檔在索引中被索引,而索引還不存在,因此老是使用模板,這一般不是一個問題,由於無類型索引調用要處理有類型的索引。
在由6.8和7.0節點組成的集羣中,應該在索引建立之類的索引API中指定參數include_type_name
,這是由於參數在6.8和7.0之間有不一樣的默認值,因此相同的映射定義對兩個節點版本都無效。
諸如bulk
和update
之類的無類型文檔API僅在7.0版本時可用,不能用於6.8節點,對於執行文檔查找的查詢的無類型版本,如terms
,也是如此。