項目中經常出現的情景,例如Elasticsearch 服務搭建好了,也建立了索引,但是現有字段不合適或者需要添加字段、修改字段,那就需要根據新的映射規則,重建索引庫。最好是項目一開始搭建時,就給索引庫一個別名,當需要修改字段時,只需要新增映射,創建新的索引庫,然后將別名指向新的索引庫,當然需要將之前的索引搬遷到新的索引庫當中。
1、獲取映射信息(例如索引庫是db_student)
GET http://localhost:9200/db_student/_mapping
這時可以看到返回結果:
{ "db_student": { "mappings": { "properties": { "chinese": { "type": "integer", "store": true }, "class": { "type": "integer", "store": true }, "english": { "type": "integer", "store": true }, "math": { "type": "integer", "store": true }, "name": { "type": "text", "store": true }, "school": { "type": "text", "store": true, "analyzer": "ik_max_word" } } } } }
這正是上一篇我們設置的映射規則,現在我們想要增加一列 desc ,用來保存學生的自我介紹介紹信息,首先,我們可以為 索引庫 db_student 取一個別名 student 。
2、為舊索引庫 db_student 起一個別名 student
PUT http://localhost:9200/db_student/_alias/student
此時,再查一下就索引庫有哪些別名:
GET http://localhost:9200/db_student/_alias
呈現的效果是:
{ "db_student": { "aliases": { "student": {} } } }
此時,別名已經生效。
3、建立新的索引庫 db_student_v1,在原索引庫的基礎上加上 desc 這一新的字段,並且使用 ik 分詞
PUT http://localhost:9200/db_student_v1 { "mappings": { "properties": { "class": { "type": "integer", "store": true, "index":true }, "chinese": { "type": "integer", "store": true, "index":true }, "english": { "type": "integer", "store": true, "index":true }, "math": { "type": "integer", "store": true, "index":true }, "name": { "type": "text", "store": true, "index":true }, "school": { "type": "text", "store": true, "index":true, "analyzer":"ik_max_word" }, "desc": { "type": "text", "store": true, "index":true, "analyzer":"ik_max_word" } } } }
4、數據搬遷,現在將索引庫 db_student 的數據搬到新的索引庫 db_student_v1
POST http://localhost:9200/_reindex { "conflicts": "proceed", "source": { "index": "db_student" }, "dest": { "index": "db_student_v1", "op_type": "create", "version_type": "external" } }
5、更改別名,將舊版索引庫 db_student 的別名去除,將別名指向新版的索引庫 db_student_v1
去除舊版索引庫 db_student 的別名:
POST http://localhost:9200/_aliases { "actions": [ { "remove": { "index": "db_student", "alias": "student" } } ] }
為新版索引庫 db_student_v1 加上別名:
POST http://localhost:9200/_aliases { "actions": [ { "add": { "index": "db_student_v1", "alias": "student" } } ] }
此時就可以統一按照別名 student 來進行上一篇的所有查詢動作,例如我們新增一個文檔(此文檔包含desc這個新的字段,插入的索引庫是 student ,指向 db_student_v1 ):
PUT http://localhost:9200/student/_doc/9 { "chinese":80, "class":10, "english":90, "math":100, "name":"Jim", "school":"華南理工大學", "desc":"來自廣東廣州,是潮汕人,英國經濟學博士" }
打開Kibana,可以看到新數據已經是插入成功了。
以上的mapping字段的設置,還是比較的簡單粗暴,典型的例如字符串,Elasticsearch 字符串的處理可以設置為 type = text 或者是 type = keyword ,區別在於text支持分詞、不支持聚合,而keyword不支持分詞、支持聚合,
在上面mapping中,school字段的type設置為text,這樣和字段desc就沒有什么區別,但實際應用中,經常會統計不同學校的各類數據,school 避免不了聚合統計,如果school的type設置為text,那么聚合就會報錯,
這是可以將type設置為keyword,再重建索引,方法如上面所介紹。
