我通过将数据移动到新索引尝试了一次别名索引,我发现它花了太长时间,遵循本指南https://www.elastic.co/blog/changing-mapping-with-zero-downtime。
此外,我有大约7500万份文件,而且每一秒都在成长。
我尝试使用elasticdump将数据从旧索引移动到新索引,但它非常慢。
我有什么最快的方法可以改变类型映射吗?
答案 0 :(得分:2)
实现此目的的一种方法是在地图中创建另一个string
字段,并将现有的long
字段修改为copy_to
到该新字段。
curl -XPUT localhost:9200/your_index/_mapping/your_type -d '{
"your_type": {
"properties": {
"long_field": {
"type": "long",
"copy_to": "str_field" <---- copy_to new field
},
"str_field": { <---- new field
"type": "string",
"store": true <---- store it if you want to see it using fields=...
}
}
}
}'
所有新索引的文档都会填充新字段str_field
。您也可以修改索引过程,直接在发送给ES的源文档中填充该新字段,当然。请注意,如果不这样做,str_field
将仅被编入索引(因此可以搜索),但它不会显示在_source
中。您仍然可以通过为该字段添加str_field
来存储"store": true
,然后在使用&fields=str_field
对于所有现有文档,该字段可以以不同的方式填充,而不得不重新索引所有内容(这会破坏目的而您只需创建一个新索引),但是巧妙地为那个新领域设置批量重新索引过程,这可以做到。
另一个核心解决方案是使用update-by-query plugin。
您仍需要将新的str_field
添加到映射中,而不修改现有映射:
curl -XPUT localhost:9200/your_index/_mapping/your_type -d '{
"your_type": {
"properties": {
"str_field": { <---- new field
"type": "string"
}
}
}
}'
然后使用该插件,您可以发出一个查询,例如这个查询将填充新字段(如果您不再需要,可以选择从源中删除long_field
:
curl -XPOST 'localhost:9200/your_index/_update_by_query' -d '{
"query" : {
"match_all" : {}
},
"script" : "ctx._source.str_field = String.valueOf(ctx._source.long_field); ctx._source.remove(\"long_field\"); "
}'
对于第二个解决方案,您需要确保在elasticsearch.yml
中启用脚本并重新启动ES:
script.inline: on
script.indexed: on
但请注意,对于第二个解决方案,除非您还调整索引过程,以便在发送给ES的JSON文档中包含新的str_field
字段,否则不会填充新字段。
答案 1 :(得分:1)
您只能通过重新创建索引来更改映射,无法就地更改映射。
因此,您可能需要找到将数据导出/导入新索引的最快方法。您可以尝试使用其中一个重建索引插件,而不是将数据导出Elasticsearch,然后将其写回,您可以在节点上本地保存数据而无需数据传输的成本,例如, https://github.com/codelibs/elasticsearch-reindexing看起来很有希望。