33、ElasticSearch 实战:映射映射到底设置了什么?

关于版本

内容 版本
Elasticsearch版本 7.2.0
JAVA依赖版本 7.2.1

索引映射

索引的映射相当于数据库中的表结构,这里我之前在相关文章中已经接单介绍过了Elasticsearch基础04——映射的操作。只不过当时只是简单介绍了下映射的相关操作,并没有详细介绍映射包含哪些内容。

映射的创建

和传统数据库不同,传统的数据库我们尝试向表中插入数据的前提是这个表已经存在数据结构的定义,且插入数据的字段要在表结构中被定义。而ES的映射的创建支持主动和被动创建。

被动创建(动态映射)

此时字段和映射类型不需要事先定义,只需要存在文档的索引,当向此索引添加数据的时候当遇到不存在的映射字段,ES会根据数据内容自动添加映射字段定义。

动态映射规则

使用动态映射的时候,根据传递请求数据的不同会创建对应的数据类型

JSON中数据类型 Elasticsearch 数据类型
null 不添加任何字段
true或者false boolean类型
浮点数据 float类型
integer数据 long类型
object object类型
array 取决于数组中的第一个非空值的类型。
string 如果此内容通过了日期格式检测,则会被认为是date数据类型。如果此值通过了数值类型检测则被认为是double或者long数据类型,带有关键字子字段会被认为一个text字段

主动创建(显示映射)

动态映射只能保证最基础的数据结构的映射,所以很多时候我们需要对字段除了数据结构定义更多的限制的时候,动态映射创建的内容很可能不符合我们的需求,所以可以使用PUT {index}/mapping来更新指定索引的映射内容。

设置防止映射过大

为索引中的列定义太多太大的字段会使得映射变得十分臃肿,从而导致内存错误和难以恢复的情况。尤其在使用动态映射的时候,新的数据中假如携带不存在的字段数据时系统会自动添加新的字段,假如不做出限制会使映射字段变得非常多。目前ES支持设置的参数有下面几个

可以设置的内容:

参数 说明
index.mapping.total_fields.limit
限制索引中字段的最大数量。默认值是1000。
index.mapping.depth.limit 字段结构中定义的最大深度,基于根节点定义的字段深度为1,,如果有一个对象映射,则深度为2,依此类推。默认值是20。
index.mapping.nested_fields.limit 索引中嵌套类型的最大数目,默认为50。
index.mapping.nested_objects.limit 索引嵌套类型的单个文档内嵌套JSON对象的最大数量,默认为10000。
index.mapping.field_name_length.limit 自定名称的最大长度,模型情况下是没有限制的。

映射中可以设置的数据类型

这个内容我之前在Elasticsearch基础05——字段类型中已经介绍过了,上面有对数据字段的简单介绍。

映射类型(Mapping Type)

6、 X之后此部分已经删除;

映射中的元信息字段

在创建映射的时候我们定义的字段内容并非映射中所有的字段,每个文档都存在一些和系统有关的元数据,这些数据被存储在映射的元字段中。

根据元数据的作用不同可以分为下面几部分:

  • 文档特征元信息
  • 文档数据源元信息
  • 索引原信息
  • 路由原信息
  • 自定义元信息

文档特征元信息

字段 说明
_index 文档所属的索引
_type 文档的映射类型。6.X之后已删除
_id 文档的ID

文档数据源元信息

字段 说明
_source 表示文档主体的原始JSON
_size _source字段的大小(以字节为单位)

需要注意的_size并不是默认就存在的。此字段需要mapper-size插件提供,该字段会以字节为单位索引_source字段的大小。

索引原信息

字段 说明
_field_names 用来索引文档中包含除了null之外的任何值得字段的名称
_ignored 该字段索引并存储文档中因为格式错误而被忽略的字段的名称

路由原信息

字段 说明
_routing 将文档路由到特定碎片的自定义路由值

在创建文档的时候添加路由参数,这样通过为每个文档指定自定义路由值来实现自定义路由模式。

PUT offline_sales/_doc/abc?routing=abcd
{
   
     
   ......
}

针对自定义路由的数据进行查询的时候可以获得_routing元信息

{
   
     
  "_index" : "offline_sales",
  "_type" : "_doc",
  "_id" : "abc",
  "_version" : 1,
  "_seq_no" : 9,
  "_primary_term" : 1,
  "_routing" : "abcd",
  "found" : true,
  "_source" : {
   
     
    ......
  }
}

自定义元信息

字段 说明
_meta 此字段可以定义一些自定的信息,这些信息Elasticsearch不会使用他们,但是用户可以用其来保存特定的元数据,比如版本信息等。

映射创建时候参数设置

除了对字段的定义,Mapping创建的时候提供了一些对于查询策略和自身定义的参数配置。下面只是简单介绍下映射支持的字段参数内容。

参数 说明
analyzer 定义此字段索引时使用的分词方式
normalizer normalizer功能类似于analyzer,但是其可以使查询条件输出唯一的查询条件(可以认为其只是实现了条件小写等不会产生多个查询条件的相关操作)
boost 定义当前字段的查询权重
coerce 此字段控制是否尝试修复部分错误的数据格式,(比如对一个整数字段插入字符串比如"5",此时此字符串可以被解析为数字),默认为true
copy_to 类似于别名,不同之处参数可以将此字段内容复制到指定字段中,多个字段可以复制到同一个字段中
doc_values 倒排索引虽然可以快速查询文档中内容,但是在进行排序或聚合操作的时候,倒排索引并不能获得文档内容,所以需要存储一份文档数据到doc_values,而此参数控制字段是否需要存储在doc_values中的开关。
dynamic 是否开启动态映射,目前支持三个参数:true/false 开启和关闭,strict 当出现未定义的字段,抛出异常并拒绝添加文档
enabled 此参数控制字段是否可以被索引,当被设置为false的时候表示此字段仅用来存储而无需索引,此时ES不会分析此字段内的数据,所以即使插入的非法的数据内容ES依旧允许执行
fielddata 类似doc_values都是单独存储额外的文档数据,这样通过倒排索引获取文档内容,从而实现在排序和聚合上的功能。不同的是doc_values不支持text格式,text格式数据需要使用fielddata。此参数默认是禁止的,这是因为在第一次对字段进行排序或聚合的时候它会把这个列数据都加载到内存中,这样会带来大量的内存消耗。
eager_global_ordinals 是否使用全局序号来进行聚合。主要在聚合分析构建hash的时候,使用序号来替代doc的值,这样在文档收集阶段根据需要收集到各个桶中,在计算结果时将序号转换为具体doc内容。但是此操作在每次查询时需要重建doc序号关系
format 日期类型字段用来解析的日期格式
ignore_above 当插入字段长度超过此字段设置的值后,此内容将不被索引或存储。对于数组结构字段会作用到每一个元素
ignore_malformed 当向一个字段插入错误的数据类似时,会抛出异常并拒绝文档。但设置此参数后,对字段插入错误的数据时会忽略异常,此文档错误的数据将不被索引,但是其他字段则正常。
index_options 控制将哪些信息添加到反向索引中
index_phrases 主要将两个单词的组合索引到单独字段中,这样在进行精确的短语查询的时候会更有效。支持true和false参数。默认为false。此参数会使索引变大
index_prefixes 允许对字段的前缀进行索引,此参数用来提高查询的速度
index 控制字段是否可以被索引,被设置为false的字段无法被索引到
fields 此参数可以为同一个字段设置不同的索引方式,但是在_source字段中只会保存一份,并不会实际增加存储。但是会增加索引大小
norms norms里面存储的是各种各样的归一化因子,此内容会影响到文档的得分,在不需要对字段进行打分的时候可以禁用此参数,需要注意的是对于keyword字段默认为false
null_value 一般来说空值是无法被索引的,但是此参数允许使用指定的值替换空值,以对其进行索引
position_increment_gap 增加近似值匹配
properties 定义类型映射、对象字段和嵌套字段等数据
search_analyzer 定义此字段查询时使用的分词方式
similarity 此参数可以配置用来计算字段相似性的算法
store 默认情况下字段内容会被索引但是并不会存储字段中的值,想获取字段中的值则需要在_source中获取对应字段的数据,当查询仅仅是尝试获取指定字段的内容的时候,可以设置此参数为true,那么系统可以直接获取此字段的内容,不再尝试获取_source中的数据。
term_vector 术语向量的定义,存储一些术语向量,以便可以为特定文档检索它们

上面只是对映射参数的简单整理,里面很多参数都涉及到Elasticsearch的查询优化、存储优化以及不同的查询以及分析功能的实现。仅仅使用一句话是没法解释其作用的效果。后续我会根据功能,对其中部分字段进行介绍。