什么是Mapping?
这个Mapping 对应关系型数据库的schema的定义,作用如下:
- 定义索引中的字段的名字
- 定义字段的数据类型,例如字符串、数字、布尔类型...
- 字段、倒排索引的相关配置,Analyzed or Not Analyzed, Analyzer
Mapping 会把JSON文档映射成Lucene 所需要的扁平格式
一个Mapping属于一个索引的Type
- 每个文档都属于一个Type
- 一个Type有一个Mapping 定义
- 7.0开始,不需要再Mapping定义中指定type信息
Elasticsearch 中当创建索引的时候,Dyamic Mapping 默认会根据索引中的字段,创建mapping 的数据类型。
Elasticsearch中的字段类型有
简单类型
- Text/Keyword
- Date
- integer / Floating
- Boolean
- IPV4 & IPV6
复杂类型
- 对象类型 / 嵌套类型
特殊类型
- geo_poing & geo_shape / percolator
什么是Dynamic Mapping?
- 在写入文档的时候,如果索引不存在,会自动创建索引
- Dynamic Mapping的机制,使得我们无需手动定义Mapping。Elasticsearch会自动根据文档信息,推算出字段的类型
- 但是有的时候推算的不准,例如地理位置信息
- 当类型设置的不对时,会导致一些功能无法正常运行,例如Range 查询
类型的自动识别
JSON类型 Elasticsearch类型 字符串
匹配日期格式,设置成Date
配置数字设置为float或者long,该选项默认关闭
设置成text,并且增加keyword 子字段
布尔值 boolean 浮点数 float 整数 long 对象 Object 数组 由第一个非空数值的类型所决定 空值 忽略
//dynamic mapping, 推断字段的类型
PUT mapping_test/_doc/1
{
"uid":"123",
"isVip":false,
"isAdmin":"true",
"age":19,
"heigh":180
}
// 查看Maping 推断的类型
GET mapping_test/_mapping
能否更改Mapping的字段类型
两种情况
- 新增加字段
- Dynamic 设为Strict时,文档写入失败
- Dynamic 设为false时,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
- Dynamic 设为true时,一旦有新增字段的文档写入,Mapping也同时被更新
- 对已有字段,一旦已经有数据写入,就不再支持修改字段的定义
- 如果希望改变字段的类型,必须Reindex APi,重建索引
- Lucene 实现的倒排索引,一旦生成后,就不允许修改
原因
- 如果修改了字段的数据类型,会导致已被索引的属于无法被搜索
- 但是如果是增加新的字段,就不会有影响
控制Dynamic Mappings
“true” | “false” | “strict” | |
文档可索引 | YES | YES | NO |
字段可索引 | YES | NO | NO |
Mapping被更新 | YES | NO | NO |
当dynamic被设置成false时候,存在新增字段的数据写入,该数据可以被索引,但是新增字段被丢弃
当设置成Strict模式的时候,数据写入直接出错
操作示例
//mapping
// 字段的数据类型
// 写入文档,查看Mapping,验证自动推断
PUT mapping_test/_doc/1
{
"firstName":"Chan",
"lastName":"Jackie",
"loginDate":"2018-07-24T10:29:48.103Z"
}
// 查看Maping
GET mapping_test/_mapping
// 删除索引
DELETE mapping_test
// 查看es 索引
GET _cat/indices
//dynamic mapping, 推断字段的类型
PUT mapping_test/_doc/1
{
"uid":"123",
"isVip":false,
"isAdmin":"true",
"age":19,
"heigh":180
}
// 查看Maping 推断的类型
GET mapping_test/_mapping
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
}
// 新增字段
PUT dynamic_mapping_test/_doc/10
{
"annotherField":"someValue"
}
// 查看结果
POST dynamic_mapping_test/_search
{
"query": {
"match": {
"annotherField": "someValue"
}
}
}
GET dynamic_mapping_test/_mapping
// 修改为dynamic strict
PUT dynamic_mapping_test/_mapping
{
"dynamic": "strict"
}
// 新增字段
PUT dynamic_mapping_test/_doc/12
{
"aa":"someValue"
}
DELETE dynamic_mapping_test
四种不同级别的倒排索引选择
- docs 记录doc id
- freqs 记录doc id 和term frequencies
- positions 记录doc id/term frequencies / term position
- offsets 记录doc id/term frequencies/term postition / character offects
Text 类型默认记录postions,其他默认docs
记录越多,占用空间越大
// 如何给索引定义mapping
PUT movies
{
"mappings": {
// define your mappings here
}
}
// 不需要索引字段、字段无法被搜索
DELETE user
PUT user
{
"mappings": {
"properties": {
"firstName": {
"type":"text"
},
"lastName": {
"type": "text"
},
"mobile": {
"type": "text",
"index": false
}
}
}
}
PUT user/_doc/1
{
"firstName": "Ruan",
"lastName": "Yiming",
"mobile": "12345678"
}
POST /user/_search
{
"query": {
"match": {
"mobile":"12345678"
}
}
}
// 需要对Null 值实现搜索
PUT user
{
"mappings": {
"properties": {
"firstName": {
"type":"text"
},
"lastName": {
"type": "text"
},
"mobile": {
"type": "keyword",
"null_value": "NULL"
}
}
}
}
PUT user/_doc/1
{
"firstName": "Ruan",
"lastName": "Yiming",
"mobile": null
}
// 只有keyword类型支持设定NUll_Value
null_value
GET user/_search?q=mobile:NULL
POST /user/_search
{
"query": {
"match_all": {}
}
}
}
// copy_to 设置
PUT user
{
"mappings": {
"properties": {
"firstName": {
"type":"text",
"copy_to": "fullName"
},
"lastName": {
"type": "text",
"copy_to": "fullName"
}
}
}
}
PUT user/_doc/1
{
"firstName": "Ruan",
"lastName": "Yiming"
}
_all 在7中被copy_to所取代
copy_to 将字段的数值拷贝到目标字段,实现类似_all 的作用
copy_to 的目标字段不会出现在_source中
GET user/_search?q=fullName:(Ruan Yiming)
//
PUT user/_doc/1
{
"name": "gnufree",
"interests": "reading"
}
PUT user/_doc/1
{
"name": "mark",
"interests": ["reading","music"]
}
POST /user/_search
{
"query": {
"match_all": {}
}
}
}
GET user/_mapping