简介

Elasticsearch在遇到文档中以前未遇到的字段,可以使用dynamic mapping(动态映射机制) 来确定字段的数据类型并自动把新的字段添加到类型映射。
Elastic的动态映射机制可以进行开关控制,通过设置mappings的dynamic属性,
dynamic有如下设置项

  • true:遇到陌生字段就执行dynamic mapping处理机制
  • false:遇到陌生字段就忽略
  • strict:遇到陌生字段就报错 ```java PUT /user { “settings”: { “number_of_shards”: 3, “number_of_replicas”: 0 }, “mappings”: { “dynamic”: “strict”, “properties”: {
    1. "name": {"type": "text"},
    2. "address": {"type": "object", "dynamic": true}
    } } }

会报错, 把没映射的age去掉就行了

PUT /user/_doc/1 { “name”: “lisi”, “age”: “20”, “address”: { “province”: “beijing”, “city”: “beijing” }

}

<a name="Dlwcd"></a>
# 映射的类型
ES是依靠JSON文档的字段类型来实现自动识别字段类型,支持的类型如下:

![image.png](https://cdn.nlark.com/yuque/0/2020/png/520075/1585640483353-f4ca6693-aa1b-4a0b-b6af-01fc2bfa344b.png#height=429&id=J2M5n&name=image.png&originHeight=429&originWidth=417&originalType=binary&ratio=1&size=28204&status=done&style=none&width=417)

```json
POST /my_index/doc
{
  "username":"whirly",
  "age":22,
  "birthday":"1995-01-01"
}
GET /my_index/_mapping

# 结果
{
  "my_index" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "birthday" : {
          "type" : "date"
        },
        "username" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

日期的自动识别

  • dynamic_date_formats 参数为自动识别的日期格式,默认为 [ “strict_date_optional_time”,”yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z”]
  • date_detection可以关闭日期自动识别机制 ```java PUT /my_index/_doc/1 { “note”: “2014-01-01” }

发现note自动映射为date类型

GET /my_index/_mapping

插入报错, 类型不对

PUT /my_index/_doc/2 { “note”: “Logged out” }

删除类型

DELETE /my_index

日期检测可以通过在根对象上设置 date_detection 为 false 来关闭, 然后现在类型就是text了

PUT /my_index { “mappings”: { “date_detection”: false } }

使用这个映射,字符串将始终作为 string 类型。如果需要一个 date 字段,必须手动添加。 Elasticsearch 判断字符串为日期的规则可以通过 dynamic_date_formats setting 来设置。
```java
# 自定义日期识别格式
DELETE /my_index

PUT /my_index
{
  "mappings": {
      "dynamic_date_formats": ["MM/dd/yyyy"]

  }
}

# 符合我们日期规则, note将会是date类型
PUT /my_index/_doc/1
{
  "note": "01/01/2014"
}

GET /my_index/_mapping

# 报错
PUT /my_index/_doc/1
{
  "note": "2014-01-11"
}

# 如果一开始note插入数据不是符合规范的日期类型, 那后面note就会被识别为text类型

数字的自动识别

  • 字符串是数字时,默认不会自动识别为整形,因为字符串中出现数字完全是合理的
  • numeric_detection 参数可以开启字符串中数字的自动识别

    Dynamic templates

    允许根据ES自动识别的数据类型、字段名等来动态设定字段类型,可以实现如下效果:

  • 所有字符串类型都设定为keyword类型,即不分词

  • 所有以message开头的字段都设定为text类型,即分词
  • 所有以long_开头的字段都设定为long类型
  • 所有自动匹配为double类型的都设定为float类型,以节省空间

Dynamic templates API

"dynamic_templates": [
    {
      "my_template_name": { 
        ...  match conditions ... 
        "mapping": { ... } 
      }
    },
    ...
]

匹配规则一般有如下几个参数:

  • match_mapping_type 匹配ES自动识别的字段类型,如boolean,long,string等
  • match, unmatch 匹配字段名
  • match_pattern 匹配正则表达式
  • path_match, path_unmatch 匹配路径

模板按照顺序来检测;第一个匹配的模板会被启用。
例如,我们给 string 类型字段定义两个模板:
es :以 _es 结尾的字段名需要使用 spanish 分词器。
en :所有其他字段使用 english 分词器。
我们将 es 模板放在第一位,因为它比匹配所有字符串字段的 en 模板更特殊:

PUT /my_index2
{
  "mappings": {
    "dynamic_templates": [
        {
          "es": {
            "match": "*_es",
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "analyzer": "spanish"
            }
          }
        },
        {
         "en": {
           "match": "*",
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "analyzer": "english"
            }
         }
        }
      ]
  }
}

GET /my_index2/_mapping

PUT /my_index2/_doc/1
{
  "name_es": "testes",
  "name": "es"
}
  1. 匹配字段名以 _es 结尾的字段
  2. 匹配其他所有字符串类型字段, match_mapping_type 允许你应用模板到特定类型的字段上,就像有标准动态映射规则检测的一样 (例 如 string 或 long)
  3. match参数只匹配字段名称,path_match 参数匹配字段在对象上的完整路径,所以 address.*.name 将匹配这样的字段
    {
    "address": {
     "city": {
       "name": "New York"
     }
    }
    }
    
# double类型的字段设定为float以节省空间
PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "integers": {
            "match_mapping_type": "double",
            "mapping": {
              "type": "float"
            }
          }
        }
      ]
    }
  }
}

自定义Mapping的建议

  1. 写入一条文档到ES的临时索引中,获取ES自动生成的Mapping
  2. 修改步骤1得到的Mapping,自定义相关配置
  3. 使用步骤2的Mapping创建实际所需索引

    动态映射

    PUT /library
    {
    "mappings": {
    "books": {
      "dynamic": "strict",
      "properties": {
        "title": {"type": "string"},
        "name": {"type": "string", "index": "not_analyzed"},
        "publish_date": {"type": "date","index": "not_analyzed"},
        "price": {"type": "double"},
        "number": {
          "type": "object",
          "dynamic": true
        }
      }
    }
    }
    }