Elasticsearch 映射类型的变迁史

2024-02-23 20:48

本文主要是介绍Elasticsearch 映射类型的变迁史,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  原文为官方文档,此篇文章为翻译,不能保证完全正确性,有地方存在歧义或者不准确,仅做参考,建议阅读官方原文:https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html

一、重要需知

  在Elasticsearch 7.0.0 或更高版本中创建的索引不再接受_default_映射。在6.x中创建的索引将继续在6.x中运行。在7.0的API中,类型已弃用,并且对索引创建、put映射、get映射、put模板、get模板和get字段映射的API进行了重大更改。

二、什么是映射类型(mapping types)?

  从Elasticsearch的第一个版本开始,每个文档都存储在一个索引中并分配了一个映射类型。映射类型用于表示要建立索引的文档或者实体的类型,例如twitter索引可能具有user(用户)类型和tweet(推文)类型。
  每种映射类型都可以有自己的字段,因此user类型可以有full_name字段、user_name字段和email字段,而tweet类型可以有content字段、tweeted_at(发布推文的时间)字段、以及和user类型类似的user_name字段。
  每个文档都有一个包含类型名称的_type元数据字段,我们可以在搜索中指定类型名称,将搜索限制在一种或多种类型。

GET twitter/user,tweet/_search
{"query": {"match": {"user_name": "kimchy"}}
}

  _type字段与文档的_id组合在一起可以生成_uid字段,因此具有相同_id的不同类型的文档可以存在于单个索引中。映射类型还用于在文档之间建立父子关系,因此question类型的文档可以是answer类型文档的父级。

三、为什么要删除映射类型?

  最初,我们谈到的“index”类似于SQL数据库中的“database”,“type”等同于“table”。这是一个不合适的类比,会导致错误的设想。在SQL数据库中,表彼此独立,一个表中的列与另一表中具有相同名称的列毫无关系,但是映射类型的字段却不是这种情况。
  在一个Elasticsearch索引中,所有不同类型的同名字段内部是由相同的Lucene字段支持。换句话说,在上面的例子中,user类型中的user_name字段和tweet类型中的user_name字段是储存在完全相同的字段中,并且两个user_name字段在这两种类型中必须具有相同的映射(定义)。例如,当您希望删除同一索引中的一种类型同名的日期字段和另一种类型同名的布尔字段时,这可能会导致问题。
  最重要的是,存储在同一索引中具有很少或没有共同字段的不同实体会导致数据稀疏,并干扰Lucene有效压缩文档的能力。
  由于这些原因,我们决定从Elasticsearch中删除映射类型的概念。

四、映射类型的替代方法

1、为每个文档类型创建一个索引

  第一个选择就是为每个文档类型创建一个索引,来代替将user和tweet都存储在twitter索引中。您可以将推文存储在tweet索引中,将用户存储在user索引中。索引之间彼此完全独立,因此索引之间的字段类型不会发生冲突。
  这种方法有两个好处:
   • 数据可能更密集,因此可以从Lucene中使用的压缩技术中受益。
   • 在全文搜索中用于评分的术语统计可能更准确了,因为同一索引中的所有文档都代表一个实体。
  每个索引的大小可以根据包含的文档数量进行适当调整,您可以为user设置使用较少数量的主分片,为tweet设置使用较大数量的主分片。

2、自定义类型字段

  当然,一个集群中可以存在多少个主要分片是有限制的,因此您可能不想只存储几千个文档就浪费了整个分片。在这种情况下,您可以实现自己的自定义类型字段,它的工作方式与旧_type相似。让我们以上面的用户/推文示例为例。
  最初,可能会这样做(6.x以下可以这么做,因为6.x每个索引只允许一个单一类型):

PUT twitter
{"mappings": {"user": {"properties": {"name": { "type": "text" },"user_name": { "type": "keyword" },"email": { "type": "keyword" }}},"tweet": {"properties": {"content": { "type": "text" },"user_name": { "type": "keyword" },"tweeted_at": { "type": "date" }}}}
}PUT twitter/user/kimchy
{"name": "Shay Banon","user_name": "kimchy","email": "shay@kimchy.com"
}PUT twitter/tweet/1
{"user_name": "kimchy","tweeted_at": "2017-10-24T09:00:00Z","content": "Types are going away"
}GET twitter/tweet/_search
{"query": {"match": {"user_name": "kimchy"}}
}

  您可以通过添加自定义类型字段来实现相同的目的,如下所示(7.x版本以下可以这么做):

PUT twitter
{"mappings": {"_doc": {"properties": {"type": { "type": "keyword" }, "name": { "type": "text" },"user_name": { "type": "keyword" },"email": { "type": "keyword" },"content": { "type": "text" },"tweeted_at": { "type": "date" }}}}
}PUT twitter/_doc/user-kimchy
{"type": "user", "name": "Shay Banon","user_name": "kimchy","email": "shay@kimchy.com"
}PUT twitter/_doc/tweet-1
{"type": "tweet", "user_name": "kimchy","tweeted_at": "2017-10-24T09:00:00Z","content": "Types are going away"
}GET twitter/_search
{"query": {"bool": {"must": {"match": {"user_name": "kimchy"}},"filter": {"match": {"type": "tweet" }}}}
}

五、文档父子关系的建立将无映射类型

  以前,通过将一种映射类型作为父级,而将另一种或多种其他映射类型作为子级来表示父子关系。没有类型,我们将无法再使用此语法。父子功能将继续像以前一样起作用,除了表达文档之间关系的方式已更改为使用新的join字段来实现。

六、删除映射类型时间表

  对于用户来说,移除映射类型这是一个很大的变化,因此我们试图使其尽可能轻松,更改将按以下方式一步步推出:

Elasticsearch 5.6.0• 在索引上设置index.mapping.single_type: true启用单一索引类型行为,该行为将在6.0中强制执行。• 在5.6中创建的父子关系上可以使用join字段替换。Elasticsearch 6.x• 在5.x中创建的索引将像在5.x中一样继续在6.x中运行。• 在6.x中创建的索引仅允许每个索引使用一种类型,该类型可以使用任何名称,但是只能有一个。首选的类型名称是_doc,因此索引API具有与7.0中相同的路径:PUT {index}/_ doc/{id} 和 POST {index}/_doc。• _type名称不能再与_id组合以形成_uid字段。_uid字段已成为_id字段的别名。   • 新索引不再支持以前文档间建立父/子关系的旧方法,而应使用join字段实现。   •  _default_ 映射类型已弃用。• 在6.8中,创建索引、索引模板和映射(mappings)的API支持查询字符串参数include_type_name,该参数表示请求和响应是否应包括类型名称,默认为true。Elasticsearch 7.x• 在请求中指定类型已经被弃用。不再为文档创建索引就必须需要一种文档类型。对于显式ID,新索引API为PUT {index}/_doc/{id};对于自动生成的ID,则为POST {index}/_doc。请注意,在7.0版本中,doc是路径的永久部分,它表示端点名称而不是文档类型了。• 索引创建、索引模板和映射(mappings)的API中的include_type_name参数将默认为false,当请求和响应中包括类型名称时将导致弃用警告。• _default_映射类型已删除。Elasticsearch 8.x• 不再支持在请求中指定类型。• include_type _name参数已删除。

七、将多类型索引迁移到单类型

  Reindex API可用于将多类型索引转换为单类型索引。以下示例可在Elasticsearch 5.6或Elasticsearch 6.x中使用。在6.x中,无需指定index.mapping.single_type,因为它是默认值。

1、为每个文档类型创建一个索引

  依照最开始的示例,我们将twitter索引分为tweets索引和users索引:

PUT users
{"settings": {"index.mapping.single_type": true},"mappings": {"_doc": {"properties": {"name": { "type": "text" },"user_name": { "type": "keyword" },"email": { "type": "keyword" }}}}
}PUT tweets
{"settings": {"index.mapping.single_type": true},"mappings": {"_doc": {"properties": {"content": { "type": "text" },"user_name": { "type": "keyword" },"tweeted_at": { "type": "date" }}}}
}POST _reindex
{"source": {"index": "twitter","type": "user"},"dest": {"index": "users","type": "_doc"}
}POST _reindex
{"source": {"index": "twitter","type": "tweet"},"dest": {"index": "tweets","type": "_doc"}
}

2、自定义类型字段

  以下示例将添加了一个自定义类型字段,并将其设置为原始_type的值。如果有任何不同类型的文档具有冲突的ID,它也会将类型添加到_id中:

PUT new_twitter
{"mappings": {"_doc": {"properties": {"type": { "type": "keyword" },"name": { "type": "text" },"user_name": { "type": "keyword" },"email": { "type": "keyword" },"content": { "type": "text" },"tweeted_at": { "type": "date" }}}}
}POST _reindex
{"source": {"index": "twitter"},"dest": {"index": "new_twitter"},"script": {"source": """ctx._source.type = ctx._type;ctx._id = ctx._type + '-' + ctx._id;ctx._type = '_doc';"""}
}

八、7.0中的无类型API的使用

  在Elasticsearch 7.0中,每个API将支持无类型的请求,如果指定了类型将产生弃用警告。但是需要注意的是,即使目标索引包含了自定义类型,无类型的API也能正常工作。例如,如果索引的自定义类型名为my_type,我们可以使用无类型索引调用向其中添加文档,也可以使用无类型get调用加载文档。如下:

PUT test/my_type/1
{"name" : "test"
}
GET test/my_type/1
GET test/_doc/1

  结果:GET获取文档数据,两者结果一样,但是前者包含了类型名称,所以会有弃用警告,后者没有。

# GET test/my_type/1
#! Deprecation: [types removal] Specifying types in document get requests is deprecated, use the /{index}/_doc/{id} endpoint instead.
{"_index" : "test","_type" : "my_type","_id" : "1","_version" : 2,"_seq_no" : 1,"_primary_term" : 1,"found" : true,"_source" : {"name" : "test"}
}# GET test/_doc/1
{"_index" : "test","_type" : "_doc","_id" : "1","_version" : 2,"_seq_no" : 1,"_primary_term" : 1,"found" : true,"_source" : {"name" : "test"}
}

1、Index APIs

  索引创建、索引模板和映射的API支持在URL中使用include_type_name参数,该参数指定请求和响应中的映射定义是否应包含类型名称,可以设置为true或false。在6.8版中,该参数默认为true,以支持在7.0之前在映射(mappings)中使用类型名称的行为。在7.0版中默认为false,在版本8.0中将被删除。
  将此选项设置为false,如下与Elasticsearch进行交互的一些示例(以下映射直接包含在映射键下,没有类型名称)。

PUT /my-index-000001?include_type_name=false
{"mappings": {"properties": { "foo": {"type": "keyword"}}}
}PUT /my-index-000001/_mappings?include_type_name=false
{"properties": { "bar": {"type": "text"}}
}GET /my-index-000001/_mappings?include_type_name=false

结果:

{"my-index-000001" : {"mappings" : {"properties" : {"bar" : {"type" : "text"},"foo" : {"type" : "keyword"}}}}
}

2、Document APIs

  在7.0中,索引API必须使用{index}/_doc路径进行调用。对于显式ID,索引API为PUT {index}/_doc/{id};对于自动生成的ID,则为POST {index}/_doc。

PUT /my-index-000001/_doc/1
{"foo": "baz"
}

结果:

{"_index" : "my-index-000001","_type" : "_doc","_id" : "1","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1
}

同样,获取和删除APl使用路径也要为{index}/_ doc/{id}:

GET /my-index-000001/_doc/1

  需要注意的是,在7.0中,_doc表示端点名称,而不是文档类型。 _doc组件是文档索引、获取和删除API路径的永久部分,在8.0中不会删除。
  对于像_update这种同时包含类型和端点名称的API路径,在7.0中,_update直接跟在索引名称后面即可:

POST /my-index-000001/_update/1
{"doc" : {"foo" : "qux"}
}GET /my-index-000001/_source/1

  类型也不应再出现在请求正文中,类型也不应再出现在请求正文中。以下创建批量索引示例在URL和单个批量命令中都省略了该类型:

POST _bulk
{ "index" : { "_index" : "my-index-000001", "_id" : "3" } }
{ "foo" : "baz" }
{ "index" : { "_index" : "my-index-000001", "_id" : "4" } }
{ "foo" : "qux" }

3、Search APIs

  调用诸如_search,_msearch或_explain之类的搜索API时,URL中不应包含类型。此外,不应在查询、聚合或脚本中使用类型字段。

4、Types in responses

  文档和搜索API将继续在回应中返回_type 键,以避免中断响应解析。但是该键被认为已弃用,不应再被引用。在8.0版中,类型将从回应中完全删除。
  请注意,当使用不推荐使用的类型API时,索引的映射类型将正常返回,但是无类型API会在响应中返回伪类型_doc。例如,即使映射具有自定义类型名称(例如my_type),以下无类型的get调用也将始终以doc作为类型返回:

PUT /my-index-000001/my_type/1
{"foo": "baz"
}GET /my-index-000001/_doc/1

结果:

{"_index" : "my-index-000001","_type" : "_doc","_id" : "1","_version" : 1,"_seq_no" : 0,"_primary_term" : 1,"found": true,"_source" : {"foo" : "baz"}
}

5、Index templates

  建议通过将include_type_name设置为false来重新添加索引模板,使索引模板无类型。在后台,无类型的模板在创建索引时将使用伪类型_doc。
  如果将无类型的模板与有类型的索引创建调用一起使用,或者将有类型的模板与无类型的索引创建调用一起使用,则仍将应用该模板,但是是否应该有一个类型将由索引的创建调用决定。
  例如,在下面的示例中,尽管index-1-01与无类型的模板匹配,但index-1-01将具有类型;尽管index-2-01与定义了类型的模板匹配,但index-2-01将是无类型的。 index-1-01和index-2-01都将从它们匹配的模板中继承foo字段。

PUT _template/template1
{"index_patterns":[ "index-1-*" ],"mappings": {"properties": {"foo": {"type": "keyword"}}}
}PUT _template/template2?include_type_name=true
{"index_patterns":[ "index-2-*" ],"mappings": {"type": {"properties": {"foo": {"type": "keyword"}}}}
}PUT index-1-01?include_type_name=true
{"mappings": {"type": {"properties": {"bar": {"type": "long"}}}}
}PUT index-2-01
{"mappings": {"properties": {"bar": {"type": "long"}}}
}

6、混合版本集群

  在由6.8和7.0节点组成的集群中,应在诸如索引创建之类的索引API中指定参数include_type_name。这是因为参数在6.8和7.0之间具有不同的默认值,因此相同的映射定义对两个节点版本均无效。
  无类型文档API(例如批量和更新)仅在7.0以后可用,不适用于6.8节点。对于执行文档查找的无类型查询,例如术语,也是如此。

这篇关于Elasticsearch 映射类型的变迁史的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/739881

相关文章

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

C#中,decimal类型使用

在Microsoft SQL Server中numeric类型,在C#中使用的时候,需要用decimal类型与其对应,不能使用int等类型。 SQL:numeric C#:decimal

说一说三大运营商的流量类型,看完就知道该怎么选运营商了!

说一说三大运营商的流量类型,看完就知道该怎么选运营商了?目前三大运营商的流量类型大致分为通用流量和定向流量,比如: 中国电信:通用流量+定向流量 电信推出的套餐通常由通用流量+定向流量所组成,通用流量比较多,一般都在100G以上,而且电信套餐长期套餐较多,大多无合约期,自主激活的卡也是最多的,适合没有通话需求的朋友办理。 中国移动:通用流量+定向流量 移动推出的套餐通常由通用流量+定向

微服务中RPC的强类型检查与HTTP的弱类型对比

在微服务架构中,服务间的通信是一个至关重要的环节。其中,远程过程调用(RPC)和HTTP是两种最常见的通信方式。虽然它们都能实现服务间的数据交换,但在类型检查方面,RPC的强类型检查和HTTP的弱类型之间有着显著的差异。本文将深入探讨这两种通信方式在类型检查方面的优缺点,以及它们对微服务架构的影响。 一、RPC的强类型检查 RPC的强类型检查是其核心优势之一。在RPC通信中,客户端和服务端都使

一二三应用开发平台应用开发示例(4)——视图类型介绍以及新增、修改、查看视图配置

调整上级属性类型 前面为了快速展示平台的低代码配置功能,将实体文件夹的数据模型上级属性的数据类型暂时配置为文本类型,现在我们调整下,将其数据类型调整为实体,如下图所示: 数据类型需要选择实体,并在实体选择框中选择自身“文件夹” 这时候,再点击生成代码,平台会报错,提示“实体【文件夹】未设置主参照视图”。这是因为文件夹选择的功能页面,同样是基于配置产生的,因为视图我们还没有配置,所以会报错。

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用 1、强引用(Strong Reference)2、软引用(Soft Reference)3、弱引用(Weak Reference)4、虚引用(Phantom Reference)5、总结 💖The Begin💖点点关注,收藏不迷路💖 在Java中,除了我们常见的强引用(Strong Refer

Flink SQL因类型错误导致MAX和MIN计算错误

背景 最近在做数据分析,用Flink SQL来做分析工具,因数据源的数据存在不太规范的数据格式,因此我需要通过SQL函数把我需要的数据值从VARCHAR类型的字段中把数据提取出来,然后再做MAX、MIN、SUM这些统计。怎料SUM算出来的结果准确无误,而MAX和MIN算出来的结果却始终不正确,最后发现原来是我用SQL函数提取VARCHAR类型的字段的数据,也是VARCHAR类型,所以导致MAX、

SQL求解两个时间差 时间类型 时间值

sql 求解两个时间差 SELECTDATEDIFF( Second, '2009-8-25 12:15:12', '2009-9-1 7:18:20') --返回相差秒数 SELECTDATEDIFF( Minute, '2009-9-1 6:15:12', '2009-9-1 7:18:20') --返回相差分钟数 SELECTDATEDIFF( Day, '2009-8

金蝶KIS新建账套时 从字符串向DateTime转换时失败 从字符串转换为Datetime类型时发生语法错误

需要修改以下几点 控制面板---区域和语言选项---区域选项---自定义,修改为如下格式

C++系统相关操作4 - 获取CPU(指令集)架构类型

1. 关键词2. sysutil.h3. sysutil.cpp4. 测试代码5. 运行结果6. 源码地址 1. 关键词 关键词: C++ 系统调用 CPU架构 指令集 跨平台 实现原理: Unix-like 系统: 可以通过 uname -m 命令获取 CPU 架构类型。Windows 系统: 可以通过环境变量 PROCESSOR_ARCHITECTURE 获取 CPU 架构类型。