# Mapping（映射）

## Mapping（映射）

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

*   哪些字符串属性应该被看做全文本属性（full text fields）。

*   哪些属性包含数字，日期或者地理位置。

*   文档中的所有属性是否都能被索引（_all 配置）。

*   日期的格式。

*   自定义映射规则来执行动态添加属性。

## Mapping Types（映射类型）

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

每一个映射类型包含：

[Meta_fields](http://www.sohu.wiki/pages/viewpage.action?pageId=9405203)（元标签）

      元标签用于制定如何处理文档相关的元数据。例如元标签包含文档的[_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](http://www.sohu.wiki/pages/viewpage.action?pageId=7372806) or properties（字段或属性）

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

## Field datatypes（字段/属性 数据类型）

每一个属性都有一个数据类型：

*   简单类型：[text](http://www.sohu.wiki/display/Elasticsearch/Text), [keyword](http://www.sohu.wiki/display/Elasticsearch/Keyword), [date](http://www.sohu.wiki/display/Elasticsearch/Date), [long](http://www.sohu.wiki/display/Elasticsearch/Numeric), [double](http://www.sohu.wiki/display/Elasticsearch/Numeric), [boolean](http://www.sohu.wiki/display/Elasticsearch/Boolean) 或者 [ip](http://www.sohu.wiki/display/Elasticsearch/IP)。
*   支持JSON层次结构的类型：[object](http://www.sohu.wiki/display/Elasticsearch/Object) 或者 [nested](http://www.sohu.wiki/display/Elasticsearch/Nested)。
*   特定类型： [geo_point](http://www.sohu.wiki/display/Elasticsearch/Geo-point), [geo_shape](http://www.sohu.wiki/display/Elasticsearch/Geo-Shape), 或者 [completion](http://www.sohu.wiki/display/Elasticsearch/Completion+Suggester)

根据不同的目的以不同的方式索引同一字段往往是有用的，例如，一个字符串字段可以作为全文本搜索的文本字段进行[索引](http://www.sohu.wiki/pages/viewpage.action?pageId=9405835)，也可以作为排序或者聚合的关键字来进行[索引](http://www.sohu.wiki/pages/viewpage.action?pageId=9405835)。另外，你可以通过[标准分词](http://www.sohu.wiki/pages/viewpage.action?pageId=10027572)，[英文分词](http://www.sohu.wiki/pages/viewpage.action?pageId=10028349#id-语言分析器-english分析器)以及[法文分词](http://www.sohu.wiki/pages/viewpage.action?pageId=10028349#id-语言分析器-french分析器)来索引一个字符串。

这就是进行multi-fields的目的。大多数数据类型都能通过[fields](http://www.sohu.wiki/pages/viewpage.action?pageId=9405837)配置来支持multi-fields。

## Settings to prevent mappings explosion

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

index.mapping.total_fields.limit

      一个索引中的字段/属性的最大数量，默认为1000.

index.mapping.depth.limit

      一个字段/属性的最大深度，用于控制内部对象的数量。例如，如果所有的字段/属性都定义为root对象级别，那么深度就为1。如果有一个对象映射，那么深度为2。默认值为20。

index.mapping.nested_fields.limit

      一个索引中嵌套字段/属性的最大值，默认为50。用100个嵌套字段索引1个文档实际上相当于索引了101个文档，因为每个嵌套文档都会作为单独的隐藏文档被索引。

## Dynamic mapping（动态映射）

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

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

## Explicit mappings（显式映射）

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

## Updating existing mappings（更新已存在的映射）

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

## Fields are shared across mapping types（映射类型中共享字段）

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

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

如果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（举例）

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

```
curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
  "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"
        }
      }
    }
  }
}
'

```