笔记十一: Dynamic Mapping 和常见字段类型
Mapping
- Mapping 类似数据库的schema的定义,作用如下
- 定义索引中的字段名称
- 定义字段的数据类型,例如字符串,数字,布尔…
- 字段,倒排索引的相关配置,(Analyzed or Not Analyzed,Analyzer)
- Mapping 会把JSON文档映射称Lucene所需的扁平格式
- 一个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 查询
类型的自动识别
JSON类型 | Elasticsearch类型 |
---|---|
字符串 | 1 匹配日期格式设置成Date |
2 设置数字设置为 float 或者long,该选项默认关闭 | |
3 设置为Text,并增加keyword子字段 | |
布尔值 | boolean |
浮点数 | float |
整数 | long |
对象 | Object |
数组 | 由第一个非空数值的类型所决定 |
空值 | 忽略 |
//写入文档
PUT mapping_test/_doc/1
{
"firstName":"Lee",
"lastName":"Crazy",
"loginDate":"2019-10-22T21:08:48"
}
//查看Mapping 文件
GET mapping_test/_mapping
{
"mapping_test" : {
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"lastName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"loginDate" : {
"type" : "date"
}
}
}
}
}
//dynamic mapping 推断字符的类型
PUT mapping_test/_doc/1
{
"uid":"123",
"isVip": false,
"isAdmin":"true",
"age": 18,
"heigh" : 180
}
//返回结果
{
"mapping_test" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"heigh" : {
"type" : "long"
},
"isAdmin" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"isVip" : {
"type" : "boolean"
},
"uid" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
能否更改Mapping 的字段类型
- 两种情况
- 新增字段
- Dynamic设置为true时,一定有新增字段的文档写入,Mapping也同时被更新
- Dynamic 设为false,Mapping不会被更新,自增字段的数据无法被索引,但是信息会出现在_source中
- Dynamic设置成Strict文档写入失败
- 对已有字段,一旦已经有数据写入,就不在支持修改字段定义
- Luene实现的倒排索引,一旦生成后,就不允许修改
- 如果希望改变字段类型,必须Reindex API,重建索引
- 新增字段
- 原因
- 如果修改了字段的数据类型,会导致已被索引的属于无法被搜索
- 但是如果是增加新的字段,就不会有这样的影响
控制 Dynamic Mappings
true | false | strict | |
---|---|---|---|
文档可索引 | YES | YES | NO |
字段可索引 | YES | NO | NO |
Mapping被更新 | YES | NO | NO |
- 当 dynamic 被设置成 false 时候,存在新增字段的数据写入,该数据可以被索引,当时新增字段被废弃
- 当设置成 Strict 模式的时候,数据写入直接出错
PS: 修改之前的数据的参数值 还是可以的.//默认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 { "anotherField":"someValue" } //重新去查询,但是anotherField 未被搜索到 POST dynamic_mapping_test/_search { "query": { "match": { "newField": "someValue" } } } //查看mapping GET dynamic_mapping_test/_mapping { "dynamic_mapping_test" : { "mappings" : { "dynamic" : "false", "properties" : { "newField" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } } } } //修改为dynamic strict PUT dynamic_mapping_test/_mapping { "dynamic": "strict" } //新增newField 报错 PUT dynamic_mapping_test/_doc/12 { "newField":"value" }
本作品采用《CC 协议》,转载必须注明作者和本文链接