Elasticsearch 版本:6.4.0
在項目中後期,若是想調整索引的 Mapping 結構,好比將 ik_smart 修改成 ik_max_word 或者 增長分片數量 等,但 Elasticsearch 不容許這樣修改呀,怎麼辦?html
常規 解決方法:mysql
<!--more-->linux
我認爲最大的弊端就是:須要修改替換程序,甚至有時候還得告知用戶暫停使用業務。sql
有沒有更好的方式去解決上面的需求呢?有!幸虧,Elasticsearch 爲咱們提供了另一種解決方法,能夠不須要告知用戶和修改程序代碼。那就是經過索引別名來重建索引。shell
索引別名能夠關聯一個或多個索引,而且能夠在任何須要索引名稱的 API 中使用。 通俗解釋,別名相似於 windows 的快捷方式,linux 的軟連接,mysql 的視圖。別名爲咱們提供了極大的靈活性。它們容許咱們執行如下操做:segmentfault
本文開頭遇到的問題,就能夠經過索引別名來實現,如今咱們學習一下具體操做。windows
如何在零停機(該索引所用到的程序不中止運行)的前提下,修改索引的 Mapping 字段類型呢?可大致分爲三步:數據結構
使用 reindex 操做來將舊索引(dynamic_data_v2)的數據徹底複製到新索引(dynamic_data_v5)上:app
POST _reindex { "source": { "index": "dynamic_data_v2" }, "dest": { "index": "dynamic_data_v5" } }
執行結果:elasticsearch
POST /_aliases { "actions": [ { "remove": { "index": "dynamic_data_v2", "alias": "dynamic_data" }}, { "add": { "index": "dynamic_data_v5", "alias": "dynamic_data" }} ] }
DELETE dynamic_data_v2
至此,咱們達到了僞更新(對於用戶來講透明化,無需中止服務)的效果。不過這裏存在一個問題,若是數據量超大的話,複製數據所消費的時間比較多,因此構建索引前仍是要儘可能考慮周全 mapping 結構。
關於索引別名更多操做,可參考:
https://www.elastic.co/guide/...
Elasticsearch 不容許修改/刪除 Mapping 已存在字段是由於:其底層使用的是 lucene 庫,索引和搜索要涉及分詞方式等操做,更改 Mapping 將意味着使已創建索引的文檔失效,因此不容許修改 已存在字段類型等設置。
但也有個別狀況:Elasticsearch 容許咱們 將字段添加到索引現有的 Mapping 結構中 或 更改現有字段的僅搜索設置。
POST dynamic_data_v2/_mapping/_doc { "properties": { "amount":{ "type":"text" } } }
PUT dynamic_data_v2/_mapping/_doc { "properties": { "amount":{ "type":"text", "fields": { "keyword": { "type": "keyword", "ignore_above": 10 } } } } } # 爲 amount 增長 multi_field # "fields": { # "keyword": { # "type": "keyword", # "ignore_above": 10 # } # }
在 Mapping 的 field 裏面設置 properties ,可使字段存儲 Object 的數據類型。如下的 name 能夠理解爲 「對象」數據類型字段:
# 新增 name 字段,附帶first的properties屬性 PUT dynamic_data_v2/_mapping/_doc { "properties": { "name":{ "properties": { "first": { "type": "text" } } } } } # 能夠支持繼續新增一個名爲last的properties屬性 PUT dynamic_data_v2/_mapping/_doc { "properties": { "name":{ "properties": { "last": { "type": "text" } } } } }
以下圖所示:
存儲數據:
# name 的對象裏面有兩個字段,分別爲:first 和 last,表明名和姓,好比「範閒」。 PUT dynamic_data_v2/_doc/1 { "name": { "first": "閒", "last": "範" } }
查詢數據:
GET dynamic_data_v2/_search { "query": { "bool": { "must": [ { "match_phrase": { "name.last": "範" } }, { "match_phrase": { "name.first": "閒" } } ] } } }
返回結果:
上述三種方式,詳情可參考:
https://www.elastic.co/guide/...
別名是個好東西,而索引別名只是別名的其中一個類型。通常在項目中後期,索引中有大量數據的時候,才能體會到索引別名的妙用。正如本文說起:
建議: 相同索引別名的物理索引有 一致的 Mapping 和 數據結構 ,以提高檢索效率。
好了各位,以上就是這篇文章的所有內容了,能看到這裏的人呀,都是人才。
白嫖很差,創做不易。 各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!
若是本篇博客有任何錯誤,請批評指教,不勝感激 !