Elasticsearch / Python - 更改映射后重新索引数据?

时间:2015-08-29 11:34:17

标签: python elasticsearch

在映射或数据类型发生变化后,我对如何在弹性搜索中重新索引数据感到困惑。

根据弹性搜索文档

  

使用滚动搜索从旧索引中提取文档,并使用批量API将它们编入新索引。许多客户端API提供了reindex()方法,可以为您完成所有这些操作。完成后,您可以删除旧索引。

这是我的旧映射

{
  "test-index2": {
    "mappings": {
      "business": {
        "properties": {
          "address": {
            "type": "nested",
            "properties": {
              "country": {
                "type": "string"
              },
              "full_address": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

新索引映射,我正在更改full_address - > location_address

{
  "test-index2": {
    "mappings": {
      "business": {
        "properties": {
          "address": {
            "type": "nested",
            "properties": {
              "country": {
                "type": "string"
              },
              "location_address": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

我正在使用python客户端进行弹性搜索

https://elasticsearch-py.readthedocs.org/en/master/helpers.html#elasticsearch.helpers.reindex

from elasticsearch import Elasticsearch
from elasticsearch.helpers import reindex
es = Elasticsearch(["es.node1"])

reindex(es, "source_index", "target_index")

但是,这会将数据从一个索引传输到另一个索引。

我如何使用它来改变我上面的情况的映射/(数据类型等)?

3 个答案:

答案 0 :(得分:4)

如果您使用scan& scroll和已经在elasticsearch的python客户端中实现的Bulk API

,那就太简单了

首先 - >通过扫描和滚动方法

获取所有文档

循环并对每个文档进行必要的修改

使用批量API

将修改后的文档插入新索引中
from elasticsearch import Elasticsearch, helpers

es = Elasticsearch()

# Use the scan&scroll method to fetch all documents from your old index

res = helpers.scan(es, query={
  "query": {
    "match_all": {}

  },
  "size":1000 
},index="old_index")


new_insert_data = []

# Change the mapping and everything else by looping through all your documents

for x in res:
    x['_index'] = 'new_index'
    # Change "address" to "location_address"
    x['_source']['location_address'] = x['_source']['address']
    del x['_source']['address']
    # This is a useless field
    del x['_score']
    es.indices.refresh(index="testing_index3")

    # Add the new data into a list
    new_insert_data.append(x)





es.indices.refresh(index="new_index")
print new_insert_data

#Use the Bulk API to insert the list of your modified documents into the database
helpers.bulk(es,new_insert_data)

答案 1 :(得分:0)

reindex() API只是将文档从一个索引“移动”到另一个索引。它无法检测/推断旧索引的文档中的字段名full_address应该是新索引中的文档中的location_address。我怀疑标准Elasticsearch客户端提供的API可以满足您的需求。我能想到实现这一目标的唯一方法是通过客户端的附加自定义逻辑维护从旧索引到新索引的字段名称字典,然后从旧索引读取文档并使用新字段将相应文档索引到新索引从字段名称字典中获取的名称。

答案 2 :(得分:0)

更新映射后,可以使用批量API更新现有文档来完成此操作。

POST / _bulk {“ update”:{“ _ id”:“ 59519”,“ _ type”:“资产”,“ _ index”:“资产”}} {“ doc”:{“ facility_id”:491},“ detect_noop”:false}

注意-使用'detect_noop'检测noop更新。