映射
映射是定义文档及其包含的字段如何存储和索引的过程,例如,使用映射来定义:
- 哪些字符串字段应该被视为全文字段。
- 哪些字段包含数字、日期或地理位置。
- 日期值的格式。
- 用于控制动态添加字段的映射的自定义规则。
映射类型
每个索引都有一个映射类型,它决定文档将如何被索引。
映射类型具有:
元字段
- 元字段用于自定义如何处理文档的关联元数据,元字段的示例包括文档的
_index
、_type
、_id
和_source
字段。
字段或属性
- 映射类型包含与文档相关的字段或属性列表。
字段数据类型
每个字段都有一个数据type
:
- 简单的类型,如
text
、keyword
、date
、long
、double
、boolean
或ip
。 - 支持 JSON 的层次结构的类型,如
object
或nested
。 - 或者像
geo_point
、geo_shape
或completion
这样的特殊类型。
为不同的目的以不同的方式索引相同的字段通常是有用的,例如,自妇产字段可以作为全文搜索的 text
字段索引,也可以作为排序或聚合的 keyword
字段索引,或者,你可以使用标准分析器、英语分析器和法语分析器索引字符串字段。
这就是多字段的目的,大多数数据类型通过 fields
参数支持多字段。
防止映射爆炸的设置
在索引中定义太多字段会导致映射爆炸,这会导致内存不足和难以恢复的情况,这个问题可能比预期的要普遍。例如,考虑这样一种情况,其中插入的每个新文档都引入了新字段,这在动态映射中非常常见,每当文档包含新字段时,这些字段就会出现在索引的映射中。这对于少量数据来说并不令人担心,但是随着映射的增长,这可能会成为一个问题,以下设置允许你限制可以手动或动态创建的字段映射的数量,以防止错误的文档导致映射爆炸:
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
- 设置字段名称的最大长度,默认值是
Long.MAX_VALUE
(没有限制),这个设置实际上并没有解决映射爆炸的问题,但是如果你想限制字段长度,那么它仍然是有用的,通常不需要设置这个设置,默认值没有问题,除非用户开始添加大量具有非常长的名称的字段。
动态映射
字段和映射类型在使用之前不需要定义,多亏了动态映射,新的字段名将自动添加,只需索引文档,可以向顶级映射类型、内部对象和嵌套字段添加新字段。
可以配置动态映射规则来定制用于新字段的映射。
显式的映射
你对数据的了解超过了 Elasticsearch 所能猜到的,因此,尽管开始动态映射可能很有用,但在某个时候,你可能希望指定自己的显式映射。
你可以在创建索引时创建字段映射,还可以使用PUT mapping
API 将字段添加到现有索引中。
更新现有字段映射
除非有文档记录,否则无法更新现有字段映射,更改映射将意味着已经索引的文档无效。相反,应该使用正确的映射创建一个新索引,并将数据重新索引到该索引中,如果只希望重命名字段而不更改其映射,那么引入别名字段可能是有意义的。
映射示例
可以在创建索引时指定映射,如下所示:
PUT my_index
{
"mappings": {
"properties": {"title": { "type": "text"},
"name": {"type": "text"},
"age": {"type": "integer"},
"created": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
}
}
}
- 创建一个名为
my_index
的索引。 - 指定映射中的字段或属性。
- 指定
title
字段包含text
值。 - 指定
name
字段包含text
值。 - 指定
age
字段包含integer
值。 - 指定
created
字段包含两种可能格式的date
值。