映射之删除映射类型
前言
在Elasticsearch 6.0.0或更高版本中创建的索引可能只包含一个映射类型。在5.x中创建索引。具有多种映射类型的将继续在Elasticsearch 6.x中发挥作用。类型将在Elasticsearch 7.0.0的api中被弃用,并在8.0.0中完全删除。
什么是映射类型
自从第一次发布Elasticsearch
以来,每个文档都存储在一个索引中,并分配了一个映射类型。映射类型用于表示被索引的文档或实体的类型,例如,一个twitter
索引可能有一个user
类型和一个tweet
类型。
每种映射类型都可以有自己的字段,因此user
类型可能有full_name
字段、user_name
字段和email
字段,而tweet
类型可能有content
字段、tweeted_at
字段和user
类型一样的user_name
字段。
每个文档都有一个包含类型名的_type
元字段,通过在URL中指定类型名,可以将搜索限制为一个或多个类型:
GET twitter/user,tweet/_search
{
"query": {
"match": {
"user_name": "kimchy"
}
}
}
_type
字段与文档的_id
相结合,生成了一个_uid
字段,因此具有相同_id
的不同_type
的文档可以存在于单个索引中。
还使用了映射类型来建立文档之间的父子关系,因此类型为question
的文档可以是类型为answer
的文档的父文档。
为什么映射类别要被移除
最初,我们谈到"index"类似于SQL数据库中的“数据库”,而“类型”相当于“表”。
这是一个错误的类比,导致了错误的假设。在SQL数据库中,表是相互独立的。一个表中的列与另一个表中具有相同名称的列没有关系。这与映射类型中的字段不同。
在Elasticsearch索引中,不同映射类型中具有相同名称的字段在内部由相同的Lucene字段支持。换句话说,使用上面的示例,user
类型中的user_name
字段与tweet
类型中的user_name
字段存储在完全相同的字段中,而且两个user_name
字段在两种类型中必须具有相同的映射(定义)。
这可能会导致问题,例如,当您希望删除同一索引中的一个类型的日期字段和另一个类型的布尔字段时。
最重要的是,存储在同一索引中具有很少或没有字段的不同实体会导致数据稀疏,并影响Lucene有效压缩文档的能力。
基于这些原因,我们决定将映射类型的概念从Elasticsearch中移除。
映射类型的替代方案
按文档类型索引
**第一种方法是为每个文档类型建立一个索引。**您可以将tweets
存储在tweets
索引中,而将user
存储在user
索引中,而不是将tweets
和user
存储在单个twitter
索引中。索引之间是完全独立的,因此在索引之间不存在字段类型的冲突。
这种方法有两个好处:
- 数据更可能是密集的,因此受益于Lucene中使用的压缩技术。
- 在全文检索中用于评分的术语统计信息更有可能是准确的,因为同一索引中的所有文档都具有代表性
自定义类型字段
当然,集群中可以存在多少主碎片是有限制的,因此您可能不希望为了一个只有几千个文档的集合而浪费整个碎片。在这种情况下,您可以实现自己的自定义类型字段,其工作方式与旧的_type
类似。
让我们以上面的user/tweet
为例。最初,工作流应该是这样的:
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"
}
}
}
你可以通过添加自定义类型字段来达到同样的效果,如下所示:
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"
}
}
}
}
}
将多类型索引迁移到单一类型
Reindex API
可用于将多类型索引转换为单类型索引。下面的例子可以用在Elasticsearch 5.6
或Elasticsearch 6.x
中。在6.x
,不需要指定index.mapping
。single_type
是默认值。
按文档类型索引
第一个例子将我们的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"
}
}
POST _reindex
{
"source": {
"index": "twitter",
"type": "tweet"
},
"dest": {
"index": "tweets"
}
}
自定义类型字段
下一个示例添加一个自定义类型字段,并将其设置为原始_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';
"""
}
}
原文地址: Removal of mapping types
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具