上一篇說到若是一個索引的mapping設置過了,想要修改type或analyzer,一般的作法是新建一個索引,從新設置mapping,再把數據同步過來。html
那麼如何實現零停機時間更新索引配置或遷移索引?這就須要用到索引的別名設置。git
思路:github
一、假設咱們的索引是demo_v1,咱們定義了一個別名demo,之後全部的操做都用別名demo操做。app
二、如今索引demo_v1的mapping設置或者其餘一些設置不知足咱們的需求了,咱們須要修改。新建一個索引demo_v2,同時設置好最新配置。curl
三、同步索引demo_v1的數據到索引demo_v2。直到同步完。elasticsearch
四、移除索引demo_v1的別名demo,同時設置索引demo_v2的別名爲demo。ide
五、刪除索引demo_v1。工具
六、遷移完成。之後若是還有設置變動,能夠按照這個思路繼續設置索引demo_v三、demo_v4……ui
接下來用一個例子說明實現過程,實際項目中我也是按這個思路作的。若是有一些命令操做看不懂,可參看上一篇文章。url
一、建立索引demo_v1
> curl -XPUT 'localhost:9200/demo_v1' {"acknowledged":true,"shards_acknowledged":true}%
二、給索引demo_v1添加幾條數據
#給索引demo_v1添加了type=fruit的3條數據,每條數據用name和tag兩個字段
> curl -XPOST 'localhost:9200/_bulk?pretty' -d' { "index" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "1" }} { "name" : "蘋果","tag":"蘋果,水果,紅富士"} { "create" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "2" }} { "name" : "香蕉","tag":"香蕉,水果,海南,彎彎,小黃人"} { "index" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "3" }} { "name" : "西瓜","tag":"西瓜,水果,圓形,綠,閏土"} '
#返回 { "took" : 34, "errors" : false, "items" : [ { "index" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "created" : true, "status" : 201 } }, { "create" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "2", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "created" : true, "status" : 201 } }, { "index" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "3", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "created" : true, "status" : 201 } } ] }
三、給索引demo_v1設置別名demo
#設置別名 > curl -XPUT 'localhost:9200/demo_v1/_alias/demo' {"acknowledged":true}%
四、使用別名查看信息
#使用別名查看一下數據,是能夠查詢到的 > curl -XGET 'localhost:9200/demo/fruit/_search?pretty' #查看mapping > curl -XGET 'localhost:9200/demo/fruit/_mapping?pretty' #返回 { "demo_v1" : { "mappings" : { "fruit" : { "properties" : { "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "tag" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } } } } } #檢索數據 > curl -XGET 'http://localhost:9200/demo/fruit/_search?pretty' -d '{ "query" : { "term" : { "tag" : "水" } } }' #返回 { "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 0.28582606, "hits" : [ { "_index" : "demo_v1", "_type" : "fruit", "_id" : "1", "_score" : 0.28582606, "_source" : { "name" : "蘋果", "tag" : "蘋果,水果,紅富士" } }, { "_index" : "demo_v1", "_type" : "fruit", "_id" : "3", "_score" : 0.27233246, "_source" : { "name" : "西瓜", "tag" : "西瓜,水果,圓形,綠,閏土" } }, { "_index" : "demo_v1", "_type" : "fruit", "_id" : "2", "_score" : 0.24257512, "_source" : { "name" : "香蕉", "tag" : "香蕉,水果,海南,彎彎,小黃人" } } ] } }
數據由於先前建立索引時沒有設置mapping,因此這些設置都是默認設置,分詞器也默認標準分詞器。
上面檢索標籤tag中帶有「水」的數據,都查詢出來了,說明默認分詞器把「水果」這個詞拆分了。
若是咱們須要tag字段按照逗號分詞,「水果」做爲一個完整的詞不拆分該怎麼弄呢?
五、新建一個索引demo_v2,同時自定義逗號分詞器,並把逗號分詞器應用到tag字段上
#新建索引demo_v2
> curl -XPUT 'http://localhost:9200/demo_v2/' -d'{ "settings": { "index": { "analysis": { "analyzer": { "douhao_analyzer": { "pattern": ",", "type": "pattern" } } }, "number_of_shards": 5, "number_of_replicas": 1 } }, "mappings": { "fruit": { "properties": { "name": { "type": "text", "index": "not_analyzed" }, "tag": { "type": "string", "analyzer": "douhao_analyzer", "search_analyzer": "douhao_analyzer" } } } } }'
#返回 {"acknowledged":true,"shards_acknowledged":true}%
關於mapping設置及分詞器設置可參見官方文檔:
https://www.elastic.co/guide/en/elasticsearch/reference/5.3/mapping.html#mapping-type
https://www.elastic.co/guide/en/elasticsearch/reference/5.3/analysis-analyzers.html
六、同步索引demo_v1中的數據到demo_v2
我使用工具elasticdump同步數據,ElasticDump是一個ElasticSearch的數據導入導出開源工具包。
官方地址:https://github.com/taskrabbit/elasticsearch-dump
同步命令以下:
> elasticdump --input='http://localhost:9200/demo_v1' --output='http://localhost:9200/demo_v2' --type=data Wed, 21 Jun 2017 09:53:15 GMT | starting dump Wed, 21 Jun 2017 09:53:15 GMT | got 3 objects from source elasticsearch (offset: 0) Wed, 21 Jun 2017 09:53:15 GMT | sent 3 objects to destination elasticsearch, wrote 3 Wed, 21 Jun 2017 09:53:15 GMT | got 0 objects from source elasticsearch (offset: 3) Wed, 21 Jun 2017 09:53:15 GMT | Total Writes: 3 Wed, 21 Jun 2017 09:53:15 GMT | dump complete
七、驗證一下demo_v2中的數據
#檢索tag中包含「水」的數據,檢索不到就是正常的 curl -XGET 'http://localhost:9200/demo_v2/fruit/_search?pretty' -d '{ "query" : { "term" : { "tag" : "水" } } }' #檢索tag中包含「水果」的數據,能夠所有檢索到 curl -XGET 'http://localhost:9200/demo_v2/fruit/_search?pretty' -d '{ "query" : { "term" : { "tag" : "水果" } } }'
八、移除索引demo_v1的別名demo,同時設置索引demo_v2的別名爲demo
curl -XPOST 'localhost:9200/_aliases?pretty' -d'{ "actions" : [ { "remove" : { "index" : "demo_v1", "alias" : "demo" } }, { "add" : { "index" : "demo_v2", "alias" : "demo" } } ]}'
九、刪除索引demo_v1
curl -XDELETE 'localhost:9200/demo_v1'
至此整個遷移完成
ok!