# 3.2.Mapping

## Mapping

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

## Mapping（映射） <a href="#mapping-ying-she-mapping-ying-she" id="mapping-ying-she-mapping-ying-she"></a>

Mapping是用来定义一个文档（document），以及它所包含的属性（field）是如何存储和索引的。比如，使用mapping来定义：

* 哪些字符串属性应该被看做全文本属性（full text fields）。
* 哪些属性包含数字，日期或者地理位置。
* 文档中的所有属性是否都能被索引（\_all 配置）。
* 日期的格式。
* 自定义映射规则来执行动态添加属性。

### Mapping Types（映射类型） <a href="#mapping-ying-she-mappingtypes-ying-she-lei-xing" id="mapping-ying-she-mappingtypes-ying-she-lei-xing"></a>

每一个索引都有一个或多个映射类型，用于在一个索引中把文档划分为具有逻辑关系的分组。比如，用户文档应该存储为user 类型，博客应该放置于blogpost类型下。

每一个映射类型包含：

[Meta\_fields](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/mapping-fields.html)（元数据）

元标签用于制定如何处理文档相关的元数据。例如元标签包含文档的 [\_index](http://www.sohu.wiki/display/Elasticsearch/_index+field), [\_type](http://www.sohu.wiki/display/Elasticsearch/_type+field),[\_id](http://www.sohu.wiki/display/Elasticsearch/_id+field), 和[\_source](http://www.sohu.wiki/display/Elasticsearch/_source+field) 字段。

[Fields ](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/mapping-types.html)or properties（字段或属性）

每一个映射类型包含有一些与该类型相关的字段或者属性。比如一个user类型也许包含title，name，age属性，而blogpost类型也许包含title, body, user\_id 和 created属性。在同一索引中，不同的映射类型下具有相同名称的属性具有相同的映射。

> 注意: 如果两个字段或者多个字段在不同type(表)的mapping中,但是这些type(表)都在相同的同一个index下,字段的映射的数据类型必须一致.

#### 字段的数据类型

每个字段有一个typed 属性,也就是字段的数据类型.

* 简单类型:[`text`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/text.html),[`keyword`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/keyword.html),[`date`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/date.html),[`long`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/number.html),[`double`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/number.html),[`boolean`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/boolean.html)或[`ip`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/ip.html)
* 支持jason层级的类型: [`object`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/object.html)或[`nested`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/nested.html)
* 特殊类型: [`geo_point`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/geo-point.html),[`geo_shape`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/geo-shape.html), 或[`completio`](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters-completion.html)

不同的场景使用不通的类型.如: 如果是一个字符串类型的字段,可以使用 `text`类型,用于全文索引. 使用 keyword 类型用于排序(sort) 或者聚合(aggregations).另外，你可以通过（分词器）标准分词英文分词，法文分词以及来索引一个字符串。

这就是进行multi-fields的目的。大多数数据类型都能通过fields配置来支持multi-fields。

#### 相关设置

接下来的设置用于限制通过人为或者动态创建field映射的数量，为了防止bad文档引起mapping explosion。

```
index.mapping.total_fields.limit
```

一个索引(index)中可拥有的最大的字段(field)数量, 默认值: 1000.

```
index.mapping.depth.limit
```

field(属性）的最大深度（嵌套），如果对象均在root下就是1，如果存在属性含有一个内部对象（object,nested），则2，默认20

直白理解就是嵌套的层数，如果超过了默认的20，则报下错误

```
{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[7bJsCFK][127.0.0.1:9300][indices:data/write/index[p]]"
      }
    ],
    "type": "illegal_argument_exception",
    "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]"
  },
  "status": 400
}
```

```
index.mapping.nested_fields.limit
```

一个index的type（表）中mapping时使用 `nested` 类型的字段最大数量默认50。

> 注意是type lavel ，并不是index lavel

如果超出会报如下错误

```
{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Limit of nested fields [50] in index [myindex33] has been exceeded"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "Limit of nested fields [50] in index [myindex33] has been exceeded"
  },
  "status": 400
}
```

### Dynamic mapping（动态映射） <a href="#mapping-ying-she-dynamicmapping-dong-tai-ying-she" id="mapping-ying-she-dynamicmapping-dong-tai-ying-she"></a>

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

通过配置[动态映射](http://www.sohu.wiki/pages/viewpage.action?pageId=9405268)规则来定制映射，用于新的类型和字段。

### Explicit mappings（显示映射） <a href="#mapping-ying-she-explicitmappings-xian-shi-ying-she" id="mapping-ying-she-explicitmappings-xian-shi-ying-she"></a>

你可以在[创建索引](http://www.sohu.wiki/pages/viewpage.action?pageId=4882789)的时候创建映射类型和字段映射，并且你可以通过[PUT mapping API](http://www.sohu.wiki/pages/viewpage.action?pageId=4882803)添加映射类型和字段到一个已经存在的索引中。

### Updating existing mappings（更新已存在的映射） <a href="#mapping-ying-she-updatingexistingmappings-geng-xin-yi-cun-zai-de-ying-she" id="mapping-ying-she-updatingexistingmappings-geng-xin-yi-cun-zai-de-ying-she"></a>

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

### Fields are shared across mapping types（映射类型中共享字段） <a href="#mapping-ying-she-fieldsaresharedacrossmappingtypes-ying-she-lei-xing-zhong-gong-xiang-zi-duan" id="mapping-ying-she-fieldsaresharedacrossmappingtypes-ying-she-lei-xing-zhong-gong-xiang-zi-duan"></a>

映射类型用于给字段分组，但是每个映射类型中的字段不是相互独立的。以下情况下的字段具有相同的映射。

* 相同名称
* 在同一索引中
* 不同的映射类型
* 映射到同一字段内部

如果title字段同时存在于user和blogpost映射类型中，那么title字段在每个类型中都有相同的映射。除了[copy\_to](http://www.sohu.wiki/pages/viewpage.action?pageId=10027040),[dynamic](http://www.sohu.wiki/pages/viewpage.action?pageId=10028289),[enabled](http://www.sohu.wiki/pages/viewpage.action?pageId=10028302),[ignore\_above](http://www.sohu.wiki/pages/viewpage.action?pageId=10028661),[include\_in\_all](http://www.sohu.wiki/pages/viewpage.action?pageId=9405298), 和[properties](http://www.sohu.wiki/pages/viewpage.action?pageId=10027013)，这些属性在每个字段中可能会有不同的设置。

通常，具有相同名称的字段也包含同样的数据类型，所以具有相同的映射不是问题。通过选择更多的描述名称能够解决冲突，如`user_title` 和`blog_title.`

### Example mapping（举例） <a href="#mapping-ying-she-examplemapping-ju-li" id="mapping-ying-she-examplemapping-ju-li"></a>

可以在创建索引的时候指定映射：

```
PUT my_index 
{
  "mappings": {
    "user": { 
      "_all":       { "enabled": false  }, 
      "properties": { 
        "title":    { "type": "text"  }, 
        "name":     { "type": "text"  }, 
        "age":      { "type": "integer" }  
      }
    },
    "blogpost": { 
      "_all":       { "enabled": false  }, 
      "properties": { 
        "title":    { "type": "text"  }, 
        "body":     { "type": "text"  }, 
        "user_id":  {
          "type":   "keyword" 
        },
        "created":  {
          "type":   "date", 
          "format": "strict_date_optional_time||epoch_millis"
        }
      }
    }
  }
}
```

* 创建了一个名为my\_index的索引
* 添加了两个type的mapping，user type（表）  和 blogpost type （表）&#x20;
* 禁用一个`meta field 类型的字段 _all`
* 每个字段映射了字段类型或属性。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiaoxiami.gitbook.io/elasticsearch/ji-chu/mapping.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
