赞
踩
原文网址:ElasticSearch--索引与类型_IT利刃出鞘的博客-CSDN博客_elasticsearch索引类型
索引 Index
单词对应:索引 index;分片 shard;类型 Type;索引集 indices index的复数方式
索引存储在一组分片中,这些分片本身就是 Lucene 索引集。 由此可见始终使用新索引的限制:Lucene索引集在磁盘空间、内存使用情况和使用的文件描述符方面具有较小但固定的开销。 出于这个原因,一个单一的大型索引比几个小型索引更有效率:Lucene 索引集的固定成本在许多文件中被更好地分摊。
另一个重要因素是您计划如何搜索数据。 当每个分片独立搜索时,Elasticsearch 最终需要合并来自所有搜索到的分片的结果。 例如,如果您搜索 10 个索引,每个索引有 5 个分片,协调搜索请求执行的节点将需要合并 5x10 = 50 个分片结果。 在这里,您还需要小心:如果有太多的分片结果要合并和/或如果您运行产生大分片响应的大量请求(当使用聚合的时候这可能很容易发生),合并所有这些分片结果的任务可能会变为 非常耗费资源,无论是CPU 还是内存。 这又会提倡减少索引集。
类型 Type
类型是将多种类型的数据存储在相同索引中的一种便捷方式,为了保持上面讲述的原因而降低索引总数。 在实现方面,它通过在搜索特定类型过滤的文档中添加 “_type” 字段用于进行过滤选择。 类型的一个很好的属性是,与搜索单个类型相比,在相同索引下多个类型的中搜索并不会增加开销:它不会更改需要合并多少个分片结果。
类型存在一些限制:
因此说类型的作用可能仅仅会在索引中类型的 Mapping 比较相似的时候比较有作用。但是,事实是在文档中的不存在的字段仍然会占据资源的事实,在数据保存在单独的索引中可能会更加严重。
至于是选择每个索引一个类型,还是每个索引多个类型,取决于我们的使用场景和硬件资源。例如如果我们将五个类型放入了一个索引中,我们也可以创建一个5个索引每个创建一个主分片。
以下问题可以帮助我们选择:
其他网址
ElasticSearch 中的索引与类型的前生今世 - 程序印象
Elasticsearch 参考指南(删除映射类型)_风继续吹 - SegmentFault 思否
问题复现
《从Lucene到Elasticsearch:全文检索实战》=> 5.3.4 静态映射
运行示例的程序时报错:Rejecting mapping update to [my_index] as the final mapping would have more than 1 type: [blogpost, user]"
类型映射
类型映射类似于数据表的 Schema, 提供了在索引中数据如何被保存和索引。
从Elasticsearch的第一个发行版开始,每一个文档都会被存储在一个单独的索引中,并且配以一个单独的映射类型。一个映射类型被用来表示被索引的文档或者实体的类型,比如一个twitter索引可能会有一个user类型和一个tweet类型。 每一个映射类型都可以有其自身的字段,所以user类型可能有一个full_name字段,一个user_name字段和一个email字段,而tweet类型可能会包含一个content字段,一个tweeted_at字段,以及与user类型中类似的user_name字段。
_type字段的值会与文档的_id字段的值组合起来生成_uid字段,所以具有相同_id的不同类型的多个文档可以共存于一个索引中。每个文档都有一个_type元字段用来保存类型名,搜索可以通过在URL中指定类型名将搜索限定于一个或多个类型中:
- GET twitter/user,tweet/_search
- {
- "query": {
- "match": {
- "user_name": "kimchy"
- }
- }
- }
移除Mapping将会是一个比较大的变化,因此 Elasticsearch 也在尽量少影响用户的前提下,做了一些功能的规划:
Elasticsearch 5.6.0
Elasticsearch 6.x
Elasticsearch 7.x
Elasticsearch 8.x
开始的时候,我们说”索引(index)”类似于SQL数据库中的”数据库”,将”类型(type)”等同于”表”。
这是一个糟糕的类比,并且导致了一些错误的假设。在SQL数据库中,表之间是相互独立的。一个表中的各列并不会影响到其它表中的同名的列。而在映射类型(mappingtype)中却不是这样的。在同一个Elasticsearch索引中,其中不同映射类型中的同名字段在内部是由同一个Lucene字段来支持的。
使用上面的例子,user类型中的user_name字段与tweet类型中的user_name字段是完全一样的,并且两个user_name字段在两个类型中必须具有相同的映射(定义)。这会在某些情况下导致一些混乱,如下:
基于这些原因,将映射类型的概念从Elasticsearch中移除。
其他网址
ElasticSearch 7.x 默认不在支持指定索引类型_周天祥的博客-CSDN博客
5.x
以下代码在5.x是成功运行的。
- put es_test
- {
- "settings":{
- "number_of_shards" : 3,
- "number_of_replicas" : 0
- },
- "mappings":{
- "books1":{
- "properties":{
- "title":{"type":"text"},
- "name":{"type":"text","index":false},
- "publish_date":{"type":"date","index":false},
- "price":{"type":"double"},
- "number":{
- "type":"object",
- "dynamic":true
- }
- }
- },
- "books2":{
- "properties":{
- "title":{"type":"text"},
- "name":{"type":"text","index":false},
- "publish_date":{"type":"date","index":false},
- "price":{"type":"double"},
- "number":{
- "type":"object",
- "dynamic":true
- }
- }
- }
- }
- }
6.x
上边5.x代码在6.x无法运行,因为6.x一个索引只能有一种类型。所以,要删掉一种:
- put es_test
- {
- "settings": {
- "number_of_shards": 3,
- "number_of_replicas": 0
- },
- "mappings": {
- "books": {
- "properties": {
- "title": {
- "type": "text"
- },
- "name": {
- "type": "text",
- "index": false
- },
- "publish_date": {
- "type": "date",
- "index": false
- },
- "price": {
- "type": "double"
- },
- "number": {
- "type": "object",
- "dynamic": true
- }
- }
- }
- }
- }
7.x
上边6.x代码在7.x无法运行,因为6.x一个索引只能有一种类型。所以,要删掉类型的指定:
- put es_test
- {
- "settings": {
- "number_of_shards": 3,
- "number_of_replicas": 0
- },
- "mappings": {
- "properties": {
- "title": {
- "type": "text"
- },
- "name": {
- "type": "text",
- "index": false
- },
- "publish_date": {
- "type": "date",
- "index": false
- },
- "price": {
- "type": "double"
- },
- "number": {
- "type": "object",
- "dynamic": true
- }
- }
- }
- }
默认索引类型是_doc,如果想改变,则配置include_type_name: true 即可(这个没有测试,官方文档说的,无论是否可行,建议不要这么做,因为elasticsearch8后就不在提供该字段)。官方文档:Removal of mapping types | Elasticsearch Guide [7.14] | Elastic
1. 每种文档类型一个索引
第一种选择就是每个文档类型对应一个索引。你可以不将tweets和users存储于同一个索引,而将它们分别存储于tweets索引和users索引中。索引之间是完全相互独立的,不同索引中的(同名的)字段类型也就不会产生冲突了。
这种方式有两个好处:
每个索引可以依据其可能的文档存储量级来设置相关的配置:可以对users使用较少的主分片,同时对tweets使用较大数量的主分片。
2. 自定义类型字段
当然,一个集群中可以创建的主分片的数量是有限制的,所以你可能不想为一个只有几千个文档的集合去浪费一整个分片。这种情况下你可以使用你自己定义的type字段,它看起来和原来的_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"
- }
- }
- }
自定义type的写法:显式type字段替代隐式_type字段
- 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"
- }
- }
- }
- }
- }
3. 在没有映射类型的情况下实现父子关系
先前,我们通过将一个映射类型指定为父,另一个或多个映射类型为子来表示父子关系。在没有类型的情况下,我们就不能使用这种语法了。父子关系的特征会向之前那样工作,不同之处在于文档之间这种关系的表示方式变成了使用新的join字段。
Reindex API可用于将多类型索引转换为单类型索引,下面的例子可以在Elasticsearch 5.6或Elasticsearch 6.x中使用。在6.x,不需要指定index.mapping.single_type,它默认值是true。
用以下两种方法处理之后,使用Logstash将处理后的索引数据迁移至高版本Elasticsearch 6.x实例中。
将Elasticsearch 5.x实例中的单索引多type数据,按照不同的type,通过reindex拆分成多个单索引单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"
- }
- }
将Elasticsearch 5.x实例中的单索引多type数据,通过reindex script方式合并成一个单索引单type数据。
- 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';
- """
- }
- }
在Elasticsearch 7.0中,每个API都支持无类型请求,指定类型将产生一个弃用警告。
即使目标索引包含自定义类型,无类型API也可以工作,例如,如果索引具有自定义类型名称my_type,则可以使用无类型index调用向其添加文档,并使用无类型get调用加载文档。
索引创建、索引模板和映射API支持一个新的URL参数(include_type_name),该参数指定请求和响应中的映射定义是否应该包含类型名称,版本6.8中的参数默认为true,以匹配在映射中使用类型名称的7.0之前的行为,它在7.0版本中默认为false,将在8.0版本中删除。
它应该在6.8中明确设置,以便准备升级到7.0,为了避免6.8中的弃用警告,可以将参数设置为true或false,在7.0中,设置include_type_name将导致一个弃用警告。
查看一些与Elasticsearch交互的例子,这个选项设置为false:映射直接包含在mappings键下,没有类型名称。
- PUT index?include_type_name=false
- {
- "mappings": {
- "properties": {
- "foo": {
- "type": "keyword"
- }
- }
- }
- }
- PUT index/_mappings?include_type_name=false
- {
- "properties": {
- "bar": {
- "type": "text"
- }
- }
- }
GET index/_mappings?include_type_name=false
上面的调用返回:
- {
- "index": {
- "mappings": {
- "properties": {
- "foo": {
- "type": "keyword"
- },
- "bar": {
- "type": "text"
- }
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。