Dynamic Mapping和常见字段类型 电脑版发表于:2020/9/25 12:13 ![elasticsearch](https://img.tnblog.net/arcimg/hb/5f1adabe8df94fdb8331eb80e393c4a3.jpeg "elasticsearch") >#Elasticsearch Request Body与Query DSL简介 [TOC] 什么是Mapping ------------ tn>Mapping 类似数据库中的schema的定义,作用如下 >- 定义索引中的字段的名称 - 定义字段的数据类型,例如字符串,数字,布尔...... - 字段,倒排索引的相关配置,(Analyzed or Not Analyzed) tn>Mapping会把JSON文档映射成Lucene所需要的扁平格式 <br/> tn>一个Mapping属于一个索引的Type >- 每个文档都属于一个Type - 一个Type有一个Mapping的定义 - 7.0开始,不需要在Mapping定义中指定type信息 字段的数据类型 ------------ >- 简单类型 - Text / Keyword - Date - Integer / Floating - Boolean - IPv4 & IPv6 - 复杂类型 - 对象和嵌套对象 - 对象类型 / 嵌套类型 - 特殊类型 - geo_point & geo_shape / percolator 什么是Dynamic Mapping ------------ - 在写入文档的时候,如果索引不存在,会自动创建索引 - Dynamic Mapping 的机制,使得我们无需手动定义Mappings。Elasticsearch 会自动根据文档信息,推算出字段的类型 - 但有时候会推算得不对,比如地理位置 - 当类型如果设置不对时,会导致一些功能无法正常运行,例如 Range 查询 tn>查看 Mapping 的代码如下 ```bash GET movies/_mappings ``` 举例 ```bash #写入文档,查看Mapping PUT mapping_test/_doc/1 { "firstName":"Chan", "lastName":"Jackie", "loginDate":"2020-09-25T11:54:00.103Z" } #查看 Mapping 文件 GET mapping_test/_mapping #删除索引 DELETE mapping_test/_doc/1 ``` ![](https://img.tnblog.net/arcimg/hb/713ab5ae555d4ce3a04f64e39b2ed668.png) tn>但我们再下面的举例时,我们发现Elasticsearch所推断出的类型并不准确,从下图来看`uid`被错误的推断出为`text`类型,`isAdmin`同样如此。 ```bash #写入文档,查看Mapping PUT mapping_test/_doc/1 { "uid":"123", "isVip":false, "isAdmin":"true", "age":19, "heigh":180 } ``` ![](https://img.tnblog.net/arcimg/hb/e6a988e82a344aa89986a381bb41eca3.png) 类型的自动识别 ------------ | | | | ------------ | ------------ | | JSON类型 | Elasticsearch 类型 | | 字符串 | - 匹配日期格式,设置成 Date <br/> - 配置数字设置为 float 或者 long,该选项默认关闭 <br/> - 设置为Test,并且增加 keyword 子字段 | | 布尔值 | boolean | | 浮点数 | float | | 整数 | long | | 对象 | Object | | 数组 | 由第一个非空数值的类型所决定 | | 空值 | 忽略 | 能否更改 Mapping 的字段类型 ------------ tn>两种情况 >- 新增加字段 1. Dynamic设为true时,一旦有新增字段的文档写入,Mapping也同时被更新。 2. Dynamic设为false时,Mapping不会更新,新增字段的数据无法被索引。 3. Dynamic设为strict时,文档写入失败 - 对已有对字段,一旦已经有数据写入,就不再支持修改字段定义 1. Lucene实现的倒排索引,一旦生成后就不允许修改 - 如果希望改变字段类型,必须 Reindex API,重建索引 1. 如果修改了字段的数据类型,会导致已被索引的属性无法被搜索 2. 但是如果是新增的字段,就不会有这样的影响 控制 Dynamic Mappings ------------ | | true | false | strict | | ------------ | ------------ | ------------ | ------------ | | 文档可索引 | YES | YES | NO | | 字段可索引 | YES | NO | NO | | Mapping被更新 | YES | NO | NO | | 区别 | 随便加字段,容易导致添加数据时报错 | 保留数据,无法更新字段 | 不能更新字段 | >- 当dynamic为false时,存在新增字段的数据可以写入,该数据可以索引,但是新增字段被丢弃。 - 当设置成 Strict 模式的时候,数据写入直接报错 代码范例 ```bash PUT movies { "mappings": { "_doc":{ "dynamic":"false" } } } ``` 举例 ```bash #默认Mapping支持dynamic,写入的文档中加入新的字段 PUT dynamic_mapping_test/_doc/1 { "newField":"someValue" } POST dynamic_mapping_test/_search { "query": { "match": { "newField": "someValue" } } } #修改为dynamic false PUT dynamic_mapping_test/_mapping { "dynamic": false } #新增 anotherField PUT dynamic_mapping_test/_doc/10 { "auotherField":"someValue" } #该字段不可以被搜索,应为dynamic已经被设置为false POST dynamic_mapping_test/_search { "query": { "match": { "auotherField": "someValue" } } } #Mapping没有更新 GET dynamic_mapping_test/_mapping #能够被文档索引 GET dynamic_mapping_test/_doc/10 #修改为strict PUT dynamic_mapping_test/_mapping { "dynamic": "strict" } #写入数据出错,HTTP Code 400,我们发现不能写入新的字段 PUT dynamic_mapping_test/_doc/12 { "lastField": "value" } ```