elasticsearch5.5 Reindex API 异步重建索引

Reindex API

这是针对Elasticsearch官方文档的 Reindex API部分的翻译。在Elasticsearch的生产环境使用中,你存储了大量的数据,如果你需要改变某个索引里的某个字段类型,或者删除某个字段,你就不得不重建索引,但是又不能影响线上服务。官方提供了 Reindex API接口,处理这种情况。
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.5/docs-reindex.html

注意

Reindex接口不提供复制源索引的设置去创建目标索引的方法。我们应该在运行_reindex操作之前,需要自己创建目标索引,并设置映射、碎片计数、副本等。

基本用法

最基本的_reindex用法只是将文档从一个索引复制到另一个索引。
下面示例:把文档从twitter索引复制到new_twitter索引:

POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}

这个请求将返回一下结果:

{
  "took" : 147,
  "timed_out": false,
  "created": 120,
  "updated": 0,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1.0,
  "throttled_until_millis": 0,
  "total": 120,
  "failures" : [ ]
}

设置version_type

设置version_type为internal

就像_update_by_query一样,_reindex获取源索引的快照,但其目标必须是不同的索引,因此不太可能发生版本冲突。 dest元素可以像索引API一样配置,以控制乐观并发控制。 只是省略version_type(如上所述)或将其设置为internal,将导致Elasticsearch盲目地将文档转储到目标中,覆盖任何碰巧具有相同类型和id的文件。概括下就是全部覆盖,示例如下:

POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "internal"
  }
}

设置version_type为external

version_type设置为external将导致Elasticsearch保留源中的版本,创建缺少的任何文档,并更新目标索引中具有旧版本的文档而不是源索引中的任何文档。概括下就是创建没有的,更新已有的,有版本的概念,示例如下:

POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  }
}

设置op_type

op_type 设置为 create将导致_reindex仅在目标索引中创建缺少的文档。 所有现有文档都会导致版本冲突,示例如下:

POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}

默认情况下,版本冲突会中止_reindex进程,但可以在正文中设置"conflicts": "proceed"来使重建继续,示例如下:

POST _reindex
{
  "conflicts": "proceed",
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}

根据限制条件重建索引

您可以通过向源添加类型或添加查询来限制文档。

根据查询限制

示例如下,这只会将kimchy制作的推文复制到new_twitter中:

POST _reindex
{
  "source": {
    "index": "twitter",
    "type": "tweet",
    "query": {
      "term": {
        "user": "kimchy"
      }
    }
  },
  "dest": {
    "index": "new_twitter"
  }
}

多index和type

源中的索引和类型都可以是多个,允许在一个请求中从许多源复制。 这将从twitterblog索引中的tweetpost类型复制文档。 它包括twitter索引中的帖子类型和blog索引中的推文类型。 如果您想要更具体,则需要使用查询。 此时不会处理ID冲突。 目标索引将保持有效,但由于迭代顺序没有明确定义,因此不容易预测哪个文档会存活。概括下,可以从多个源重建索引到一个目标索引,但是创建索引时ID相同,后面的覆盖前面的,示例如下

POST _reindex
{
  "source": {
    "index": ["twitter", "blog"],
    "type": ["tweet", "post"]
  },
  "dest": {
    "index": "all_together"
  }
}

限制数量

也可以通过设置大小来限制处理文档的数量。 这只会将一个文档从twitter复制到new_twitter,示例如下:

POST _reindex
{
  "size": 1,
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}

限制排序和数量

如果您需要来自twitter索引的特定文档集,则需要进行排序。 排序使滚动效率降低,但在某些情况下,它是值得的。 如果可能,请选择更具选择性的查询来进行大小和排序。概括下,可以先排序再重建部分索引, 这会将10000个文件从twitter复制到new_twitter,示例如下:

POST _reindex
{
  "size": 10000,
  "source": {
    "index": "twitter",
    "sort": { "date": "desc" }
  },
  "dest": {
    "index": "new_twitter"
  }
}

重建部分字段索引

源部分支持搜索请求中支持的所有元素(The source section supports all the elements that are supported in a search request.)。概括下,可以只重建部分字段的索引,其余字段舍弃 例如,可以使用源过滤重新索引原始文档中的一部分字段,如下所示:

POST _reindex
{
  "source": {
    "index": "twitter",
    "_source": ["user", "tweet"]
  },
  "dest": {
    "index": "new_twitter"
  }
}

支持脚本

脚本允许修改文档元数据

_update_by_query一样,_reindex支持修改文档的脚本。 与_update_by_query不同,允许脚本修改文档的元数据。 这个例子颠覆了源文档的版本(这个脚本意思是,foo字段值为bar时,重建索引时版本加一并移除foo字段):

POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  },
  "script": {
    "inline": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
    "lang": "painless"
  }
}

脚本设置ctx.op

就像在_update_by_query中一样,您可以设置ctx.op来更改在目标索引上执行的操作:

空操作
如果脚本确定不必在目标索引中编制索引,请设置ctx.op =“noop”。 这种无操作将在响应机构的noop计数器中报告( This no operation will be reported in the noop counter in the response body)。

POST _reindex
{
  "source": {
    "index": "irl"
  },
  "dest": {
    "index": "docker-cluster",
    "version_type": "external"
  },
  "script": {
    "inline": "if (ctx._source.columnName == '领导活动') {ctx.op = 'noop'}",
    "lang": "painless"
  }
}

返回数据:

{
  "took": 181,
  "timed_out": false,
  "total": 626,
  "updated": 0,
  "created": 2,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 624,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": []
}

删除
如果脚本确定必须从目标索引中删除文档,请设置ctx.op =“delete”。 删除将在响应正文中的已删除计数器中报告(The deletion will be reported in the deleted counter in the response body.)。

POST _reindex
{
  "source": {
    "index": "irl"
  },
  "dest": {
    "index": "docker-cluster2"
  },
  "script": {
    "inline": "if (ctx._source.columnName == '领导活动') {ctx.op = 'delete'}",
    "lang": "painless"
  }
}

结果:

{
  "took": 103,
  "timed_out": false,
  "total": 626,
  "updated": 0,
  "created": 2,
  "deleted": 624,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": []
}

将ctx.op设置为其他任何内容都是错误的。 在ctx中设置任何其他字段是错误的。
上面的内容概括下,ctx.op只允许设置为noop或delete,作用是重建索引时符合要求的文档不做任何操作(noop)或删除(delete),并不会重建索引,这些文档的数量会在返回值中展示

修改核心元数据值

想想可能性! 小心点! 影响很大… 你可以改变(Think of the possibilities! Just be careful! With great power…. You can change这段没太懂,后续再补充):

  • _id
  • _type
  • _index
  • _version
  • _routing
  • _parent

将_version设置为null或从ctx映射中清除它就像不在索引请求中发送版本一样。 无论目标版本或您在_reindex请求中使用的版本类型如何,都会导致该文档被覆盖在目标索引中。

默认情况下,如果_reindex看到带有路由的文档,则除非脚本更改了路由,否则将保留路由。 您可以在dest请求上设置路由以更改此设置:
保持(keep
将针对每个匹配发送的批量请求的路由设置为匹配上的路由。 默认。
丢弃(discard
将针对每个匹配发送的批量请求的路由设置为null。
= <某些文字>(=<some text>
将针对每个匹配发送的批量请求的路由设置为=之后的所有文本。

例如,您可以使用以下请求将源索引source中的所有文档与公司名称cat复制到目标索引dest ,并将路由设置为cat

POST _reindex
{
  "source": {
    "index": "source",
    "query": {
      "match": {
        "company": "cat"
      }
    }
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}

默认情况下,_reindex使用1000的滚动批次。您可以使用source元素中的size字段更改批量大小:

POST _reindex
{
  "source": {
    "index": "source",
    "size": 100
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}

Reindex还可以通过指定如下管道来使用“摄取节点”功能(Reindex can also use the Ingest Node feature by specifying a pipeline like this:):

POST _reindex
{
  "source": {
    "index": "source"
  },
  "dest": {
    "index": "dest",
    "pipeline": "some_ingest_pipeline"
  }
}

从远程地址重建索引

Reindex支持从远程Elasticsearch集群重建索引:

POST _reindex
{
  "source": {
    "remote": {
      "host": "http://otherhost:9200",
      "username": "user",
      "password": "pass"
    },
    "index": "source",
    "query": {
      "match": {
        "test": "data"
      }
    }
  },
  "dest": {
    "index": "dest"
  }
}

host参数必须包含空间,主机和端口(例如https:// otherhost:9200)。用户名和密码参数是可选的,当它们存在时,reindex将使用基本身份验证连接到远程Elasticsearch节点。使用基本身份验证时务必使用https,否则密码将以纯文本格式发送。

必须使用reindex.remote.whitelist属性在elasticsearch.yaml中将远程主机明确列入白名单。它可以设置为允许的远程主机和端口组合的逗号分隔列表(例如otherhost:9200,另一个:9200,127.0.10。:9200,localhost:)。白名单忽略Scheme - 仅使用主机和端口。

此功能适用于您可能会找到的任何Elasticsearch版本的远程集群。这应该允许您通过从旧版本的群集重新索引从任何版本的Elasticsearch升级到当前版本。

要启用发送到旧版Elasticsearch的查询,请将查询参数直接发送到远程主机,而不进行验证或修改。

未完待续

猜你喜欢

转载自blog.csdn.net/u010882234/article/details/87715389
今日推荐