Elasticsearch 2.3.0 重建索引

原创
2016/05/27 11:55
阅读数 1.5K

重建索引是2.3.0新增加的接口。这个接口是实验性质的,在未来有可能会改变。

重建索引的最基本的功能是拷贝文件从一个索引到另一个索引,例如:

POST /_reindex
{
  "source": {
    "index": "secisland"
  },
  "dest": {
    "index": "new_secisland"
  }
}

返回的内容如下:

{
  "took" : 639,
  "updated": 112,
  "batches": 130,
  "version_conflicts": 0,
  "failures" : [ ],
  "created": 12344
}

took:从开始到结束的整个操作的毫秒数。

updated:已成功更新的文档数。

created:成功创建的文档数。

batches:拉回来从建索引的数量。

version_conflicts:重建索引中版本冲突数的数量。

failures:所有索引失败的数组。如果这是非空的,则请求将被中止。

    由于_reindex是获取源索引的快照,而且目标索引是不同的索引,随意基本上不太可能产生冲突。在接口参数中可以增加dest来进行乐观并发控制。如果version_type设置为internal会导致Elasticsearch盲目转储文件到目标索引,任何具有相同的类型和ID的文档将被从写。例如:

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

    如果设置version_type为external将会导致Elasticsearch保护源索引的版本,如果在目标索引中有一个比源索引旧的版本,则会更新文档。对于源文件中丢失的文档在目标中也会被创建。

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

    设置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 的文档。

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

    在请求接口中可以列出源索引和类型,可以在一个接口中复制多个源。例如下面的例子将在twitter和blog索引中的tweet和post类型中拷贝数据,这包括twitter索引中的"tweet"和"post"类型,也包括blog索引中的"tweet"和"post"类型。如果需要更具体的文档可以使用查询。当id产生冲突的时候是没有办法处理的,因为执行的顺序是随机的,所以目标索引将无法确定应该保存哪些文档。

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

    也可以通过设置大小来限制处理文档的数量。这只会复制一个文件到new_twitter索引中。

本文由赛克 蓝德(secisland)原创,转载请标明作者和出处。

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

    如果你想要复制特定的文档,可以使用排序。排序会降低效率,但在某些情况下,它是有意义的。如果可能的话,可以选择性的查询来确定复制的大小和排序。下面将从twitter索引中复制10000文档到new_twitter中。

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

    _reindex同时支持使用脚本来修改文档。例如:

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

    可以修改的元字段包括_id、_type、_index、_version、_routing、_parent、_timestamp、_ttl。所以用脚本复制能力非常强大。

    默认情况下,如果_reindex可以设置文档路由来进行路由保存除非是通过脚本进行了改变。你可以设置dest 参数来进行路由设置:

keep:设置在匹配的每一个路由上发送请求的路由。这个是默认设置。

discard:为每一个匹配发送的请求设置为空。

=<some text>:设置为每一个匹配的文本请求发送路由上的路由。例如,您可以使用以下要求复制所有文件从源索引为"company"等于"cat"的查询中复制到目标索引,目标索引的路由设置为cat。

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

    默认情况下_reindex每次处理的大小为100。可以在源参数中用size参数来进行修改:

POST /_reindex
{
  "source": {
    "index": "source",
    "size": 1500
  },
  "dest": {
    "index": "dest"
  }
}

URL参数:

    _reindex接口除了接收标准的参数例如pretty,还支持refresh, wait_for_completion, consistency, timeout参数。

在url参数中发送refresh会导致请求写的所有索引都将被刷新。这个时候收到新的数据也被索引。

如果请求包含wait_for_completion = FALSE,Elasticsearch将进行执行前检查后启动请求,然后返回一个可用于任务API取消或得到任务的状态,现在一旦请求完成任务就不见了,找任务的最终结果的唯一地方是在Elasticsearch日志文件中,这个问题将会在未来的版本中修复。

consistency控制每次写请求必须多少份分片被响应。

timeout控制每个写请求等待可用的分片的时间。

任务查看:

GET /_tasks/?pretty&detailed=true&actions=*reindex

返回的结果类似

{
  "nodes" : {
    "r1A2WoRbTwKZ516z6NEs5A" : {
      "name" : "Tyrannus",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1:9300",
      "attributes" : {
        "testattr" : "test",
        "portsfile" : "true"
      },
      "tasks" : {
        "r1A2WoRbTwKZ516z6NEs5A:36619" : {
          "node" : "r1A2WoRbTwKZ516z6NEs5A",
          "id" : 36619,
          "type" : "transport",
          "action" : "indices:data/write/reindex",
          "status" : {    
            "total" : 6154,
            "updated" : 3500,
            "created" : 0,
            "deleted" : 0,
            "batches" : 36,
            "version_conflicts" : 0,
            "noops" : 0
          },
          "description" : ""
        }
      }
    }
  }
}

_reindex可以用来建立索引的时候同时也可以修改列的名称,例如,源索引类型为:

POST test/test/1?refresh&pretty
{
  "text": "words words",
  "flag": "foo"
}

可以通过_reindex来修改列的名称,例如:

POST _reindex?pretty
{
  "source": {
    "index": "test"
  },
  "dest": {
    "index": "test2"
  },
  "script": {
    "inline": "ctx._source.tag = ctx._source.remove(\"flag\")"
  }
}

然后我们看一下test2的结构,可以看出flag字段名称修改成了tag。

GET test2/test/1?pretty
{
  "text": "words words",
  "tag": "foo"
}

赛克蓝德(secisland)后续会逐步对Elasticsearch的最新版本的各项功能进行分析,近请期待。

展开阅读全文
打赏
0
14 收藏
分享
加载中
更多评论
打赏
0 评论
14 收藏
0
分享
在线直播报名
返回顶部
顶部