3.2.Mapping

Mapping

字段的类型可以通过手动mapping创建,但是不能修改已经mapping过的字段,但可以新增字段数据类型的mapping.

Mapping(映射)

Mapping是用来定义一个文档(document),以及它所包含的属性(field)是如何存储和索引的。比如,使用mapping来定义:
  • 哪些字符串属性应该被看做全文本属性(full text fields)。
  • 哪些属性包含数字,日期或者地理位置。
  • 文档中的所有属性是否都能被索引(_all 配置)。
  • 日期的格式。
  • 自定义映射规则来执行动态添加属性。

Mapping Types(映射类型)

每一个索引都有一个或多个映射类型,用于在一个索引中把文档划分为具有逻辑关系的分组。比如,用户文档应该存储为user 类型,博客应该放置于blogpost类型下。
每一个映射类型包含:
Meta_fields(元数据)
元标签用于制定如何处理文档相关的元数据。例如元标签包含文档的 _index, _type,_id, 和_source 字段。
Fields or properties(字段或属性)
每一个映射类型包含有一些与该类型相关的字段或者属性。比如一个user类型也许包含title,name,age属性,而blogpost类型也许包含title, body, user_id 和 created属性。在同一索引中,不同的映射类型下具有相同名称的属性具有相同的映射。
注意: 如果两个字段或者多个字段在不同type(表)的mapping中,但是这些type(表)都在相同的同一个index下,字段的映射的数据类型必须一致.

字段的数据类型

每个字段有一个typed 属性,也就是字段的数据类型.
不同的场景使用不通的类型.如: 如果是一个字符串类型的字段,可以使用 text类型,用于全文索引. 使用 keyword 类型用于排序(sort) 或者聚合(aggregations).另外,你可以通过(分词器)标准分词英文分词,法文分词以及来索引一个字符串。
这就是进行multi-fields的目的。大多数数据类型都能通过fields配置来支持multi-fields。

相关设置

接下来的设置用于限制通过人为或者动态创建field映射的数量,为了防止bad文档引起mapping explosion。
1
index.mapping.total_fields.limit
Copied!
一个索引(index)中可拥有的最大的字段(field)数量, 默认值: 1000.
1
index.mapping.depth.limit
Copied!
field(属性)的最大深度(嵌套),如果对象均在root下就是1,如果存在属性含有一个内部对象(object,nested),则2,默认20
直白理解就是嵌套的层数,如果超过了默认的20,则报下错误
1
{
2
"error": {
3
"root_cause": [
4
{
5
"type": "remote_transport_exception",
6
"reason": "[7bJsCFK][127.0.0.1:9300][indices:data/write/index[p]]"
7
}
8
],
9
"type": "illegal_argument_exception",
10
"reason": "Limit of mapping depth [20] in index [my_index11] has been exceeded due to object field [manager.name.first.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last.last]"
11
},
12
"status": 400
13
}
Copied!
1
index.mapping.nested_fields.limit
Copied!
一个index的type(表)中mapping时使用 nested 类型的字段最大数量默认50。
注意是type lavel ,并不是index lavel
如果超出会报如下错误
1
{
2
"error": {
3
"root_cause": [
4
{
5
"type": "illegal_argument_exception",
6
"reason": "Limit of nested fields [50] in index [myindex33] has been exceeded"
7
}
8
],
9
"type": "illegal_argument_exception",
10
"reason": "Limit of nested fields [50] in index [myindex33] has been exceeded"
11
},
12
"status": 400
13
}
Copied!

Dynamic mapping(动态映射)

字段和映射在被使用前是不需要定义的。可以通过索引一个文档来自动添加新的映射和字段名。可以向顶层映射类型和内部对象以及嵌套字段中添加新的字段。
通过配置动态映射规则来定制映射,用于新的类型和字段。

Explicit mappings(显示映射)

你可以在创建索引的时候创建映射类型和字段映射,并且你可以通过PUT mapping API添加映射类型和字段到一个已经存在的索引中。

Updating existing mappings(更新已存在的映射)

除了documented的地方,存在的类型和字段映射不能被更新。改变映射意味着让已经索引的文档失效。相反,你应该使用正确的映射以及重新索引数据来创建新的索引。

Fields are shared across mapping types(映射类型中共享字段)

映射类型用于给字段分组,但是每个映射类型中的字段不是相互独立的。以下情况下的字段具有相同的映射。
  • 相同名称
  • 在同一索引中
  • 不同的映射类型
  • 映射到同一字段内部
如果title字段同时存在于user和blogpost映射类型中,那么title字段在每个类型中都有相同的映射。除了copy_to,dynamic,enabled,ignore_above,include_in_all, 和properties,这些属性在每个字段中可能会有不同的设置。
通常,具有相同名称的字段也包含同样的数据类型,所以具有相同的映射不是问题。通过选择更多的描述名称能够解决冲突,如user_titleblog_title.

Example mapping(举例)

可以在创建索引的时候指定映射:
1
PUT my_index
2
{
3
"mappings": {
4
"user": {
5
"_all": { "enabled": false },
6
"properties": {
7
"title": { "type": "text" },
8
"name": { "type": "text" },
9
"age": { "type": "integer" }
10
}
11
},
12
"blogpost": {
13
"_all": { "enabled": false },
14
"properties": {
15
"title": { "type": "text" },
16
"body": { "type": "text" },
17
"user_id": {
18
"type": "keyword"
19
},
20
"created": {
21
"type": "date",
22
"format": "strict_date_optional_time||epoch_millis"
23
}
24
}
25
}
26
}
27
}
Copied!
  • 创建了一个名为my_index的索引
  • 添加了两个type的mapping,user type(表) 和 blogpost type (表)
  • 禁用一个meta field 类型的字段 _all
  • 每个字段映射了字段类型或属性。
Last modified 2yr ago