elasticsearch移除映射類型(mapping type)


移除映射類型(mapping type)

es在8.X之前的邏輯存儲模型是模擬關系型數據庫的三層結構:index(庫)-type(表)-document(record).這種結構在7.x時不再推薦使用,8.x的時候會把type移除變成最終的兩級結構:index(庫)-document(record).由於層級的調整,在7.x中影響范圍包括:index creation, put mapping, get mapping, put template, get template and get field mappings APIs.

什么是映射類型(mapping type)

es中每個文檔存儲在一個索引(index)中,同時分配到一個映射類型(mapping type)中.映射類型通常表示文檔類型和索引實體.如一個twitter索引可能有user類型和tweet類型.每個映射類型有自己的字段,所以user類型可能有full_name,user_name,email字段,tweet類型可能有content,tweeted_at,user_name字段.文檔通過_type元數據字段來標識類型名稱.查詢時也通過類型字段來限制查詢范圍:

GET twitter/user,tweet/_search
{
  "query": {
    "match": {
      "user_name": "kimchy"
    }
  }
}

映射類型的缺點

關系數據庫中,每個表是獨立的,表間的字段即使同名也互相沒有干擾.但是es中的映射類型不同.

  1. es中同一個索引下的同名字段會被Lucene存儲在一起,這也要求它們的映射類型必須一致.如果不一致則會導致數據刪除失敗.
  2. 同一個索引中存儲不同的實體,往往相同字段很少,由於es的數據存儲是以索引為維度的,這就造成實際存儲的數據比較分散,不利於文檔壓縮.

這也看出來映射類型的存在很雞肋,因此es決定7.x時移除映射類型的概念.這也是基於查詢和存儲的效率最佳選擇.

推薦的映射類型方式

  • 按文檔類型划分索引

實際存儲時,不再通過映射類型區分文檔類型,而是通過索引來區分.如上面的twitter索引示例,我們把user存到user索引中,把tweet存到tweet索引中,查詢,存儲完全獨立.

優點:

  1. 數據更密集,有利於lucene壓縮
  2. 同一索引中文檔數據表示獨立的實體,使得全文檢索條目排名分析更精確.
  • 自定義類型字段(custome type field)

由於集群中主分片數量是有限的,你可能不想浪費整個分片存儲一些很少數量的文檔數據.這種情況下,你可以通過自定義類型字段實現類似之前映射類型的功能.

用上面的user/tweet舉例:

7.x之前的版本存儲流程如下:

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"
    }
  }
}

7.x之后的版本通過添加自定義類型(type)字段存儲方式:

PUT twitter?include_type_name=true
{
  "mappings": {
    "_doc": {
      "properties": {
        "type": { "type": "keyword" }, 
        "name": { "type": "text" },
        "user_name": { "type": "keyword" },
        "email": { "type": "keyword" },
        "content": { "type": "text" },
        "tweeted_at": { "type": "date" }
      }
    }
  }
}

7.x之后明確指定類型(type)字段,而7.x之前是隱式指定的_type字段

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" 
        }
      }
    }
  }
}
  • 父子結構(Parent/Child)不再提供映射類型

7.x前,parent-child關系,定義映射關系時可以指定parent和children類型.7.x后不使用這個語法.parent-child特性運行不做改變,但是實際關系表示改為通過join字段實現.

7.0無類型接口(typeless apis)

7.x作為過渡版本,它在弱化類型的實際影響.正常api使用中如果你明確指定了類型(type),會得到一個不推薦警告:

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
  • 索引APIs

索引創建,索引模板和映射apis支持新的url參數include_type_name.它指明在請求和響應映射定義中是否包含類型名稱.這個參數默認值在6.8中是true,以匹配7.0前的映射類型匹配問題.7.0后的默認值為false,8.0中將移除.

PUT /my-index-000001?include_type_name=false
{
  "mappings": {
    "properties": { 
      "foo": {
        "type": "keyword"
      }
    }
  }
}

新增索引映射時不進行類型映射.

  • 文檔APIs

7.x中,索引APIs必須通過{index}/_doc路徑調用,自動生成_id或指明{index}/_doc/{id}中的id.

PUT /my-index-000001/_doc/1
{
  "foo": "baz"
}

實際存儲數據

{
  "_index": "my-index-000001",
  "_id": "1",
  "_type": "_doc",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}

獲取和刪除APIs也類似:{index}/_doc/{id}

GET /my-index-000001/_doc/1
  • 查詢APIs

當調用像_search, _msearch, 或_explain查詢API時,url中不應該包含類型.此外,_type字段不用於查詢,聚合和腳本中.

  • 響應中的類型

文檔和查詢APIs的響應將繼續返回_type關鍵字,避免破壞現在的響應解析.然而,這個關鍵字不再推薦也不再被引用.在8.0中將被完全刪除.

  • 索引模板

推薦在重新添加索引無類型模板時將include_type_name設置為false.后台實現中,無類型模板在創建指令中模仿類型_doc進行創建.

實際官方文檔中還展示舊版到新版的數據遷移方式,以及進行映射類型版本支持的計划.點擊參考資料即可獲取.

參考資料

removal-of-types


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM