1、ES中的_type
是什么?
从 Elasticsearch 的第一个版本开始,每个文档都存储在一个索引中并分配一个_type
。_type
用于表示被索引的文档或实体的类型,例如 person
索引可能具有man
类型和woman
类型。
每个_type
都可以有自己的字段,因此该man
类型可能有一个 full_name
字段、一个user_name
字段和一个email
字段,而该 woman
类型可以有一个age
字段、一个sex
字段,并且与 man
类型一样,还有一个user_name
字段。
每个文档都有一个_type
包含类型名称的元字段,通过在 URL 中指定类型名称,可以将搜索限制为一种或多种类型:
GET person/man,woman/_search
{
"query": {
"match": {
"man_name": "elastic"
}
}
}
复制
2、官方为什么要删除_type
这个概念
最初,官方谈到“索引”类似于 SQL 数据库中的“数据库”,“类型”相当于“表”。
这是一个糟糕的类比,导致了错误的假设。在 SQL 数据库中,表是相互独立的。一个表中的列与另一个表中的同名列无关。对于_type
中的字段,情况并非如此。
在 Elasticsearch 索引中,不同_type
中具有相同名称的字段在内部由相同的 Lucene 字段支持。换句话说,使用上面的示例,类型中的user_name
字段与man
类型中的字段存储在完全相同的user_name
字段中woman
,并且两个 user_name
字段在两种类型中必须具有相同的映射(定义)。
例如,当你想deleted
成为 同一索引中的一种date
类型的字段和另一种类型的字段时,就会很尴尬。boolean
最重要的是,在同一索引中存储具有很少或没有共同字段的不同实体会导致数据稀疏并干扰 Lucene 有效压缩文档的能力。
由于这些原因,官方决定从 Elasticsearch 中删除_type
的概念。
3、后续版本替代方案
ES 自版本 5.0 起,官方一直在为从 Elasticsearch 中移除_type
而铺平道路,终于自版本 7.0 起,实现了_type
弃用。使用_type
的初衷是在与 Lucene 不兼容的单个索引中提供多租户,但事实证明,_type
带来的问题比解决的问题还多。官方对是否应解决这一问题进行了长时间的讨论(例如,每个_type
使用唯一的字段或在底层每个_type
具有一个索引),最终官方决定移除对_type
的支持。为了让用户更轻松地过渡,官方将更改分散在了四个主要版本中:
•5.0 开始,强制跨多个_type
共享同一名称的字段具有兼容的映射。•6.0 开始,禁止新索引具有多个_type
,并弃用了 _default_
映射。•7.0 弃用了接受_type
的 API,引入了新的无_type
API,并移除了对 _default_
映射的支持。7.x 为过度版本,所有索引的_type
统一使用固定的_doc
替代•8.0 将移除接受_type
的 API。
4、7.x中_type
API的使用
在 URL 路径、请求正文或响应正文中接受_type
的所有 API 将获得一个新的“无_type
”对应项。部分特别常用的 API(如索引创建、索引和 GET API)都会发生这种情况。一例胜万言,来看一个使用无_type
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"
}
}
}
}
复制
5、低版本如何升级ES 7.x?
某些更改会造成中断,需要你在升级到 7.0 之前对集群执行一些更改。某些其他更改仅在升级到 8.0 时需要,应在升级到 7.0 之后执行。
5.1 升级之前
5.1.1 确保你的ES版本是 6.8
如果你计划以滚动方式进行无中断升级,应先升级到 6.8;在 6.x 的各个版本中,只有此版本具有支持 include_type_name
参数等功能,而对该参数的支持是顺利升级到 7.0 所必需的。
5.1.2 停止使用
default
映射7.0 中将停用 _default_
映射。如果一些现有 6.x 索引具有 _default_
映射,可以继续使用,因为仅新索引才会拒绝 _default_
映射。
请更新索引模板和应用程序代码,将这些映射添加到实际_type
,而不是将它们包括在 _default_
映射中。如果_type
名称对你不重要,建议使用 _doc
,有助于你未来更轻松地过渡到无_type
API。
5.1.3 将 include_type_name=true
传递到索引创建、模板和映射 API
迁移到无_type
API 意味着,以前在请求正文中需要_type
的 API 现在应具有其他格式:
•create index•put mapping•put template
而在响应中返回_type
的其他 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"
}
}
}
}
}
复制
5.2 升级之后
如果你遵循了建议的升级前步骤,则一切应正常运行。但在此阶段,因为你仍在使用接受_type
的 API,这会触发弃用警告。为了避免此情况,请迁移到无_type
API。
对于索引创建、模板和映射 API,需要从不再包含_type
的 URL 参数、更改请求正文或有关响应格式的要求中移除 include_type_name=true
。通常,如果请求正文或响应包含映射,则其中会包含一个类似以下内容的部分:
{
"my_type": { // this key is no longer accepted in mappings as of 7.0
"properties": ...
}
}
复制
更新之后不再包含类型名称,格式如下:
{
"properties": ...
}
复制
对于其他API,如index、GET或 Update API,应该把URL中的类型名称替换为固定值:' _doc '。例如,如果你曾经对一个类型名为' my_type '的索引执行索引调用,索引调用如下所示:
PUT index/my_type/1
{
"@timestamp":"2019-02-20"
}
复制
and should be replaced with that:
PUT index/_doc/1
{
"@timestamp":"2019-02-20"
}
复制
长按三连
每天学习更多 硬 知识
觉得内容还不错的话,给我点个“在看”呗
