5.Mapping
什么是 Mapping?
Mapping(映射)定义字段名称、数据类型、优化信息(比如是否索引)、分词器,有点类似于数据库中的表结构定义。一个 Index 对应一个 Mapping。
Mapping 分为动态 Mapping 和显示 Mapping 两种:
动态Mapping:根据待索引数据自动建立索引、自动定义映射类型。
显示Mapping:手动控制字段的存储和索引方式比如哪些字符串字段应被视为全文字段。
动态 Mapping 使用起来比较简单,在初学 Elasticsearch 的时候可以使用。实际项目中,应该尽量手动定义映射关系。
为什么插入数据不用指定 Mapping?
因为在写入文档时,如果索引不存在,Elasticsearch 会自动根据数据类型 自动推断 Mapping 信息(Dynamic Mapping),但有时候不是很准确。
有自定义过 Mapping 吗?你是怎么做的?
如果纯手写的话,工作量太大,还容易写错,所以一般采用:
- 创建临时 Index,插入一些临时数据;
- 访问 Mapping API ,获取相关 Mapping 定义;
- 在此基础上进行修改,如添加 keyword,nested类型;
- 删除临时 Index。
动态 Mapping 有几种属性配置?
4 种,可在Mapping中配置dynamic=true / runtime / false / strict(默认为true)
dynamic=true: 新字段被添加到映射中(默认)dynamic=runtime:新字段作为运行时字段添加到映射中,这些字段未编入索引,并_source在查询时加载
dynamic=false:新字段将被忽略,这些字段不会被索引或可搜索
dynamic=strict: 如果检测到新字段,则会抛出异常并拒绝文档,新字段必须显式添加到映射中
动态 Mapping 如何防止字段无限增加?
如果使用了动态映射,插入的每个新文档都可能引入新字段。在索引中定义太多字段会导致 映射爆炸 , 从而导致内存不足的错误和难以恢复的情况。使用 映射限制设置 来限制字段映射的数量(手动或动态创建)并防止映射爆炸。
index.mapping.total_fields.limit:限制了索引中的字段最大数量。字段、对象映射以及字段别名计入此限制,默认值为 1000。限制的目的是为了防止映射和搜索变得太大。较高的值会导致性能下降和内存问题,尤其是在负载高或资源很少的集群中。
index.mapping.depth.limit:字段的最大深度,以内部对象的数量来衡量。如果所有字段都在根对象级别定义,则深度为 1。如果有一个对象映射,则深度为 2 ,默认为 20。index.mapping.nested_fields.limit:nested 索引中不同映射的最大数量, nested 类型只应在需要相互独立地查询对象数组时使用,默认为 50。
index.mapping.nested_objects.limit:单个文档可以包含的嵌套 JSON 对象( nested 类型)的最大数量,默认为 10000。
index.mapping.field_name_length.limit:设置字段名称的最大长度,默认为Long.MAX_VALUE (无限制)。
index.mapping.dimension_fields.limit:仅供 Elastic 内部使用,索引的最大时间序列维度数;默认为 16。
想要某个字段不被索引怎么做?
在 Mapping 中设置属性 index = false ,则该字段不可作为检索条件,但结果中还是包含该字段与此相关的属性还有
index_options 可以控制倒排索引记录内容,属性有:
docs : 只包括 docID
freqs : 包括 docID/词频
options :默认属性,docID/词频/位置
offsets : docID/词频/位置/字符偏移量
记录内容越多,占用空间越大,但是检索越精确