在 Elasticsearch 7.0 中从类型迁移到无类型 API | Elastic Blog
工程

告别类型。迎接无类型。

自版本 5.0 起,我们一直在为从 Elasticsearch 中移除类型而铺平道路,终于自版本 7.0 起,实现了类型弃用。使用类型的初衷是在与 Lucene 不兼容的单个索引中提供多租户,但遗憾的是,事实证明,类型带来的问题比解决的问题还多。 我们对是否应解决这一问题进行了长时间的讨论(例如,每个类型使用唯一的字段或在底层每个类型具有一个索引),最终我们决定移除对类型的支持。为了让用户更轻松地过渡,我们将更改分散在了四个主要版本中:

  • 5.0 开始,强制跨多个类型共享同一名称的字段具有兼容的映射。
  • 6.0 开始,禁止新索引具有多个类型,并弃用了 _default_ 映射。
  • 7.0 弃用了接受类型的 API,引入了新的无类型 API,并移除了对 _default_ 映射的支持。
  • 8.0 将移除接受类型的 API。

无类型 API

在 URL 路径、请求正文或响应正文中接受类型的所有 API 将获得一个新的“无类型”对应项。部分特别常用的 API(如索引创建、索引和 GET API)都会发生这种情况。一例胜万言,我们来看一个使用无类型 API 与 7.0 集群交互的例子:

PUT index
{
  "mappings": {
    "properties": { // Note how there is no top-level key with the type name
      "@timestamp": {
        "type": "date"
      }
    }
  }
}
PUT index/_doc/1 // _doc becomes the new endpoint for document index, get and delete requests
{
  "@timestamp":"2019-02-20"
}
POST index/_bulk
{"index": {"_id":"2"}} // no _type in the URL or in document metadata
{"@timestamp":"2019-03-01"}
{"update": {"_id":"1"}}
{"@timestamp":"2019-02-21"}
GET index/_doc/2
GET index/_search // unchanged, the `GET index/{type}/_search` endpoint is deprecated however
{
  "query": {
    "range": {
      "@timestamp": {
        "gte":"2019-01-01"
      }
    }
  }
}
GET index/_explain/1 // note how the type does not appear in the URL anymore, this would have been "GET index/{type}/1/_explain" in 6.x
{
  "query": {
    "range": {
      "@timestamp": {
        "gte":"2019-01-01"
      }
    }
  }
}

我需要做什么?

某些更改会造成中断,需要您在升级到 7.0 之前对集群执行一些更改。某些其他更改仅在升级到 8.0 时需要,应在升级到 7.0 之后执行。

升级之前

确保您在使用 6.8

如果您计划以滚动方式进行无中断升级,应先升级到 6.8;在 6.x 的各个版本中,只有此版本具有支持 include_type_name 参数等功能,而对该参数的支持是顺利升级到 7.0 所必需的。

停止使用 _default_ 映射

7.0 中将停用 _default_ 映射。如果一些现有 6.x 索引具有 _default_ 映射,可以继续使用,因为仅新索引才会拒绝 _default_ 映射。

请更新索引模板和应用程序代码,将这些映射添加到实际类型,而不是将它们包括在 _default_ 映射中。如果类型名称对您不重要,建议使用 _doc,有助于您未来更轻松地过渡到无类型 API。

include_type_name=true 传递到索引创建、模板和映射 API

迁移到无类型 API 意味着,以前在请求正文中需要类型的 API 现在应具有其他格式:

  • create index
  • put mapping
  • put template

而在响应中返回类型的其他 API 将具有其他响应格式:

  • get index
  • get mapping
  • get field mapping
  • get template

为了不被此更改中断,请让应用程序将 include_type_name=true 传递到这些 API 调用;此参数在 6.x 中是一个 no-op 指令,且将要求 7.x 让这些 API 的行为与 6.x 中一致。例如,以下是使用此参数的索引创建调用。其在 6.8 和 7.x 上的行为方式相同。

PUT index?include_type_name=true
{
  "mappings": {
    "my_type": {
      "properties": { // Note how there is no top-level key with the type name
        "@timestamp": {
          "type": "date"
        }
      }
    }
  }
}

升级之后

如果您遵循了建议的升级前步骤,则一切应正常运行。但在此阶段,因为您仍在使用接受类型的 API,这会触发弃用警告。为了避免此情况,请迁移到无类型 API。

对于索引创建、模板和映射 API,需要从不再包含类型的 URL 参数、更改请求正文或有关响应格式的要求中移除 include_type_name=true。通常,如果请求正文或响应包含映射,则其中会包含一个类似以下内容的部分:

{
  "my_type": { // this key is no longer accepted in mappings as of 7.0
    "properties": ...
  }
}

It needs to be updated to no longer include a type name, and would now look like that:

{
  "properties": ...
}

For other APIs like the index, GET, or update API, you should replace the type name in the URL with _doc.This will work regardless of the name of the type of your index.For instance if you used to perform index calls for an index whose type name is my_type, the index call looked like this:

PUT index/my_type/1
{
  "@timestamp":"2019-02-20"
}

and should be replaced with that:

PUT index/_doc/1
{
  "@timestamp":"2019-02-20"
}

了解详情

如需了解有关移除类型以及如何迁移到无类型 API 的更多信息,建议查看我们关于移除类型的文档,从中更详细地了解有关这些更改的影响,以及如何为这些更改做好准备。

下载 7.0.0,试试这些新的无类型 API,并在讨论中告知我们您的想法。