Dynamic Mapping - 动态映射

在默认情况下,当索引一个文档时有字段是在映射中没有配置的,那么 Elasticsearch 将会根据该属性的类型,自动将其增加到映射中。

Dynamic Mapping测试

下面的POST请求会创建一个新的索引,并往里面插入一条文档:

POST /my-index/_doc
{
  "tags": ["computer", "electronics"],
  "in_stock": 4,
  "created_at": "2022/01/01 00:01:02"
}

my-index索引之前没有被创建过,尝试获取它的Mapping信息:

image-20220724155452264

会发现:

  1. created_at字段会自动被解析成date类型
  2. in_stock传入的是json的整型,但被解析成了long类型
  3. tags同时被解析成了text和keyword两种类型,即上一章提到的multi-field mapping

下图是动态映射时JSON字段与Elasticsearch字段的对应关系:

image-20220723204954191

dynamic mapping的配置

动态映射的配置可以接受以下 3 种选择:

  1. true:默认配置,新字段将会自动加入映射中,并自动推断字段的类型。
  2. false:新字段不会增加到映射中,因此不能被搜索,但是内容依然会保存在_source中。这样可以避免创建索引,从而提高插入数据的性能。
  3. strict:索引文档时如果发现有新字段则报错,整个文档都不会被索引。

dynamic=false 测试

我们先来测试将映射设置为false的效果。

创建people索引,除了场景mapping的属性,同时设置dynamic=false:

PUT /people
{
  "mappings": {
    "dynamic": false,
    "properties": {
      "first_name":{
        "type": "text"
      }
    }
  }
}

创建mapping完成后,往里面插入一条文档,这条文档除了first_name字段外,还有额外的last_name字段,此时依然可以插入成功:

image-20220724162029186

获取mapping字义,由于dynamic mapping被设置为false,此时last_name字段不再被自动mapping:

image-20220724162105148

使用first_name来搜索,可以搜索到结果:

image-20220724162157384

使用last_name搜索,不能搜索到结果

image-20220724162224584

总结dynamic设置为false后的效果:新字段不会增加到映射中,因此不能被搜索,但是内容依然会保存在_source中。这样可以避免创建索引,从而提高插入数据的性能。

dynamic=strict 测试

先将上一步创建的people索引删除:

image-20220724162757393

再重新创建索引,此时将dynamic设置为strict:

PUT /people
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "first_name":{
        "type": "text"
      }
    }
  }
}

往里面插入文档,这条文档除了first_name字段外,还有额外的last_name字段。 此时发现直接报错:

image-20220724163001923

所以,dynamic = strict的效果是:索引文档时如果发现有新字段则报错,整个文档都不会被索引。这和关系型数据相似,在关系数据库中,如果插入表字义中不存在的字段,也会报错