当拥有大量数据时,将type_mapping从long更改为字符串的最快方法是什么?

时间:2015-10-07 12:16:51

标签: elasticsearch bigdata reindex

我通过将数据移动到新索引尝试了一次别名索引,我发现它花了太长时间,遵循本指南https://www.elastic.co/blog/changing-mapping-with-zero-downtime

此外,我有大约7500万份文件,而且每一秒都在成长。

我尝试使用elasticdump将数据从旧索引移动到新索引,但它非常慢。

我有什么最快的方法可以改变类型映射吗?

2 个答案:

答案 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看起来很有希望。