原英文版地址: https://www.elastic.co/guide/en/elasticsearch/reference/7.7/mapping.html, 原文档版权归 www.elastic.co 所有
本地英文版地址: ../en/mapping.html

映射(mapping)

映射(mapping)是定义如何存储和索引文档及其包含的字段的过程。 例如,可以使用映射来定义:

  • 哪些字符串字段应被视为全文字段。
  • 哪些字段包含数字、日期或地理位置。
  • 日期值的格式(format)
  • 控制动态添加字段映射的自定义规则。

映射的定义具有:

元字段(meta-fields)
元字段(meta-fields)用于定制如何处理文档关联的元数据。 元字段的例子包括文档的 _index_id_source字段。
字段(fields)属性(properties)
映射包含与文档相关的 字段(field) 或 属性(properties) 的列表。

在7.0.0之前,mappings定义曾经包含 type。 更多信息请参考 删除的映射类型

字段数据类型

每个字段都有一个数据类型(type),可以是:

出于不同的目的,以不同的方式索引同一个字段通常是有用的。 例如,一个string字段可以索引(indexed)为一个text字段用于全文搜索,也可以索引为一个keyword字段用于排序或聚合。 或者,你可以使用standard分析器english分析器french分析器来索引一个 string 字段。

这就是 多字段(multi-fields) 的目的。 大多数数据类型通过参数fields支持多字段。

防止映射爆炸的设置

在索引中定义太多字段会导致映射爆炸,从而导致内存不足错误和难以恢复的情况。

考虑这样一种情况,其中插入的每个新文档都引入了新的字段,例如动态映射(dynamic mapping)。 每个新字段都被添加到索引的映射中,随着映射的增长,这可能会成为一个问题。

使用以下设置来限制(手动或动态创建的)字段映射的数量,并防止文档导致映射爆炸:

index.mapping.total_fields.limit

索引中字段的最大数量。字段和对象映射以及字段别名都计入此限制。默认值为 1000

这个限制是为了防止映射和搜索变得太大。 较大的值可能会导致性能下降和内存问题,尤其是在负载高或资源少的集群中。

如果增加了此设置,我们建议也增加indices.query.bool.max_clause_count设置,该设置限制查询中布尔(bool)子句的最大数量。

如果字段映射中包含一组大型的任意键,请考虑使用flattened数据类型。

index.mapping.depth.limit
字段的最大深度,以内部对象的数量来度量。 例如,如果所有字段都是在根对象级别定义的,那么深度就是1。 如果有一个对象映射,则深度为2,等等。默认值为20
index.mapping.nested_fields.limit
索引中不同 嵌套的(nested) 映射的最大数量。 nested类型应该只在特殊情况下使用:当对象数组需要彼此独立地查询时。 为了防止映射设计不当,该设置限制了每个索引的唯一的nested类型的数量。 默认值为50
index.mapping.nested_objects.limit
单个文档在所有nested类型中可以包含的嵌套(的)JSON对象的最大数量。 此限制有助于防止由于文档包含太多嵌套对象而直到内存不足的错误。 默认值为10000
index.mapping.field_name_length.limit
字段名的最大长度设置。 这个设置并不能真正解决映射爆炸的问题,但是如果你想要限制字段长度,它可能仍然有用。 通常没有必要设置这个设置。 默认设置就可以了,除非用户开始添加大量具有很长名称的字段。 默认值为Long.MAX_VALUE (没有限制)。

动态映射 (dynamic mapping)

在使用之前,不需要定义字段和映射类型。 得益于dynamic mapping,只需对文档进行索引,新的字段名称就会自动添加。 新字段既可以添加到顶级映射类型,也可以添加到内部objectnested字段。

动态映射规则可以配置为用于定制新字段的映射。

显式映射 (explicit mapping)

你对数据的了解要比Elasticsearch所能猜测的多得多,因此尽管动态映射在刚开始时很有用,但在某个时候你会希望显式的去指定自己的映射。

创建索引向已有的映射中添加字段时,可以创建字段映射。

使用显示映射创建索引

可以使用创建索引(create index)API创建一个带有显式映射的新索引。

PUT /my-index
{
  "mappings": {
    "properties": {
      "age":    { "type": "integer" },  
      "email":  { "type": "keyword"  }, 
      "name":   { "type": "text"  }     
    }
  }
}

创建一个integer类型的字段:age

创建一个keyword类型的字段:email

创建一个text类型的字段:name

向已有的映射中添加字段

可以使用put mappingAPI向已有的索引添加一个或多个新字段。

下面这个示例添加一个index映射参数值为falsekeyword类型的字段employee-id。 这意味着字段employee-id的值被存储,但是不会被索引,也就不能用于搜索。

PUT /my-index/_mapping
{
  "properties": {
    "employee-id": {
      "type": "keyword",
      "index": false
    }
  }
}

更新映射的一个字段

除了受支持的映射参数之外,不能更改现有字段的映射或字段类型。 更改已有字段可能会使已经索引的数据无效。

如果需要更改字段的映射,请创建一个具有正确映射的新索引,并将数据重新索引(reindex)到该索引中。

重命名一个字段会使已在旧字段名称下索引的数据失效。 相反,应该添加一个alias(别名)字段来创建备用字段名称。

查看一个索引的映射定义

可以使用get mappingAPI来查看已有索引的映射。

GET /my-index/_mapping

API返回下面的响应:

{
  "my-index" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "integer"
        },
        "email" : {
          "type" : "keyword"
        },
        "employee-id" : {
          "type" : "keyword",
          "index" : false
        },
        "name" : {
          "type" : "text"
        }
      }
    }
  }
}

查看特定字段的映射

如果只想查看一个或多个特定字段的映射,可以使用get field mapping API。

如果不需要索引的完整映射,或者索引包含大量字段,这将非常有用。

下面这个请求检索字段employee-id的映射。

GET /my-index/_mapping/field/employee-id

API返回下面的响应:

{
  "my-index" : {
    "mappings" : {
      "employee-id" : {
        "full_name" : "employee-id",
        "mapping" : {
          "employee-id" : {
            "type" : "keyword",
            "index" : false
          }
        }
      }
    }
  }
}