重建索引是为什么?什么时候需要重建索引?
比如,我们插入一条数据:
PUT /my_index/my_type/3
{
"title": "2017-01-03"
}
title本来只想让它是string类型,但是由于第一条数据插入时es会自动创建映射,将“2017-01-03”映射成date类型:
{
"my_index": {
"mappings": {
"my_type": {
"properties": {
"title": {
"type": "date"
}
}
}
}
}
}
这样我们如果再插入一条数据,就会报错:
PUT /my_index/my_type/4
{
"title": "my first article"
}
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "failed to parse [title]"
}
],
"type": "mapper_parsing_exception",
"reason": "failed to parse [title]",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Invalid format: \"my first article\""
}
},
"status": 400
}
此时修改title类型是不行的,这时就要重建索引,将旧索引的数据查询出来,导入新索引。
如果说旧索引是old_index,新索引时new_index,终端java应用已经在使用old_index在操作了,我们当然不能停止java应用去修改索引,这样使可用性降低。
1、给java应用提供一个别名,这个别名指向旧索引:
PUT /my_index/_alias/goods_index
2、新建一个索引,调整其title类型为string
PUT /my_index_new
{
"mappings": {
"my_type": {
"properties": {
"title": {
"type": "text"
}
}
}
}
}
3、使用scroll api将数据批量查出来
GET /my_index/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": ["_doc"],
"size": 1
}
{
"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAADpAFjRvbnNUWVZaVGpHdklqOV9zcFd6MncAAAAAAAA6QRY0b25zVFlWWlRqR3ZJajlfc3BXejJ3AAAAAAAAOkIWNG9uc1RZVlpUakd2SWo5X3NwV3oydwAAAAAAADpDFjRvbnNUWVZaVGpHdklqOV9zcFd6MncAAAAAAAA6RBY0b25zVFlWWlRqR3ZJajlfc3BXejJ3",
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": null,
"hits": [
{
"_index": "my_index",
"_type": "my_type",
"_id": "2",
"_score": null,
"_source": {
"title": "2017-01-02"
},
"sort": [
0
]
}
]
}
}
4、用bulk api将数据批量写入新索引
POST /_bulk
{ "index": { "_index": "my_index_new", "_type": "my_type", "_id": "2" }}
{ "title": "2017-01-02" }
5、重复3/4步骤,将数据写入新索引
6、将goods_index alias切换到my_index_new上去,java应用会通过别名使用索引中的数据,java应用不用停机
POST /_aliases
{
"actions": [
{ "remove": { "index": "my_index", "alias": "goods_index" }},
{ "add": { "index": "my_index_new", "alias": "goods_index" }}
]
}
7、直接通过新索引查询是否有数据
GET /goods_index/my_type/_search
总结:
整理笔记,希望对大家有用!