Elasticsearch应用(五)
1.目标
咱们这一章主要学习Mapping(映射)
2.介绍
Mapping是对索引库中文档的约束,类似于数据表结构,作用如下:
- 定义索引中的字段的名称
- 定义字段的数据类型,例如字符串,数字,布尔等
- 字段,倒排索引的相关配置(Analyzer)
3.映射类型
动态映射
介绍
在关系型数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段,类型,长度,主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映射,在文档写入Elasticsearch时,会根据文档自动识别类型,这种机制称之为动态映射
缺点
动态映射(Dynamic Mapping)的机制,使得我们无需手动定义Mappings,Elasticsearch会自动根据文档信息,推算出字段的类型。但是有时候会推算的不对,例如地理位置信息。当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询
自动识别的类型
静态映射
静态映射是在Elasticsearch中也可以实现定义好映射,包含文档的各字段类型,分词器等,这种方式称之为静态映射
4.常见的字段类型
核心类型 | 具体类型 | 说明 |
---|---|---|
字符串类型 | text | 可分词的文本 |
不分词的字符串 | keyword | 精确值,例如:品牌,国家,IP地址等 不能被分词 |
整数类型 | long,integer,short,byte | 在ES中id应该是个字符串keyword而不是数值类型 |
浮点类型 | double,float,half_float,scaled_float | |
日期类型 | date,date_nanos | |
布尔类型 | boolean | |
数组类型 | array | 数组类型不存在,里面是什么就是很么类型 |
对象类型 | object | |
地理位置类型 | geo_point,geo_shape | |
补全类型 | completion | 自动补全功能所需要的类型 |
二进制类型 | binary | |
范围类型 | integer_range,float_range,long_range,double_range,date_range,ip_range | |
JSON对象数组 | nested |
5.常见的Mapping属性
属性 | 含义 |
---|---|
type | 字段数据类型 |
index | 是否创建索引,默认为true |
analyzer | 使用那种分词器 |
properties | 该字段的子字段 |
copy_to | 字段拷贝,可以将当前字段拷贝到指定字段 |
store | 是否单独存储。如果设置为true,则该字段能够单独查询 |
boost | 控制算分 |
coerce | |
doc_values | |
dynamic | 动态映射设置 |
eager_global_ordinals | |
enabled | |
fielddata | |
fields | |
format | |
ignore_above | |
ignore_malformed | |
index_options | 控制倒排索引记录的内容 |
index_phrases | |
index_prefixes | |
meta | |
normalizer | |
norms | |
null_value | 对NULL值进行搜索 |
position_increment_gap | |
search_analyzer | |
similarity | |
term_vector |
6.能否后期更改Mapping的字段类型
两种情况
- 新增字段
- 对已有字段修改(有数据写入后)
新增字段
- dynamic设为true时,一旦有新增字段的文档写入,Mapping也同时被更新
- dynamic设为false,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
- dynamic设置成strict(严格控制策略),文档写入失败,抛出异常
对已有字段修改(有数据写入后)
- Lucene实现的倒排索引,—旦生成后,就不允许修改
- 如果希望改变字段类型,必须Reindex APl,重建索引
原因
- 如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
- 但是如果是增加新的字段,就不会有这样的影响
总结
7.对已有字段的mapping修改
步骤
- 如果要推倒现有的映射, 你得重新建立一个静态索引
- 然后把之前索引里的数据导入到新的索引里
- 删除原创建的索引
- 为新索引起个别名, 为原索引名
索引数据迁移API
POST _reindex
{"source":{"index":"user"},"dest":{"index":"user2"}
}
使用别名兼容原有的索引
PUT /user/_alias/user
8.索引基础操作
创建索引的时候指定Mapping
PUT /[索引名称]
{"mappings":{"properties":{"字段名":{"type":"text","analyzer":"ik_smart"},"字段名2":{"type":"keyword","index":false},"字段名3":{"properties":{"子字段":{"type":"keyword"}}}} }
}
获取索引的字段Mapping
介绍
检索一个或多个字段的映射定义。如果您不需要索引的完整映射或索引包含大量字段,这将很有用
请求路径
GET /_mapping/field/[字段名]GET /[索引名]/_mapping/field/[字段名]
请求示例
GET publications/_mapping/field/title
GET publications/_mapping/field/author.id,abstract,name
GET publications/_mapping/field/a*
获取某个索引的映射信息
GET /索引名/_mapping
9.Mapping属性解读
字段拷贝(copy_to)
介绍
- 该参数允许将多个字段的值复制到copy_to的字段上
- copy_to的字段支持查询
- 如果有多个字段需要查询,可以尝试把多个字段的值拷贝到一个新字段上
- 可以将相同的值复制到多个字段, “copy_to”: [ “field_1”, “field_2” ]
示例
PUT /[索引名]
{"mappings":{"properties":{"name":{"type":"text","analyzer":"ik_max_word","copy_to":"all"},"business":{"type":"keyword","copy_to":"all"},"all":{"type":"text","analyzer":"ik_max_word"}}}
}
index
介绍
控制当前字段是否被索引,默认为true。如果设置为false,该字段不可被搜索
示例
PUT /[索引名]
{"mappings":{"properties":{"name":{"type":"text","index":false}}}
}
index_options
介绍
控制倒排索引记录的内容
可选值
- docs: 记录doc id
- freqs: 记录doc id和term frequencies(词频)
- positions: 记录doc id / term frequencies / term position
- offsets: doc id / term frequencies / term posistion / character offects
- 注意: text类型默认记录postions,其他默认为docs。记录内容越多,占用存储空间越大
示例
PUT /[索引名]
{"mappings":{"properties":{"name":{"type":"text","index_options":"offsets"}}}
}
null_value
介绍
需要对NULL值进行搜索,只有keyword类型支持设计Null_value
示例
PUT /[索引名]
{"mappings":{"properties":{"name":{"type":"keyword","null_value":"NULL"}}}
}
Dynamic Template
介绍
根据Elasticsearch识别的数据类型,结合字段名称,来动态设定字段类型
示例
- 所有的字符串类型都设定成Keyword,或者关闭keyword字段
- is开头的字段都设置成boolean
- long_开头的都设置成long类型
PUT /[index]
{"mappings":{"dynamic_templates":[{"full_name":{"path_match":"name.*","path_unmatch":"*.middle","mapping":{"type":"text","copy_to":"full_name"}}}]}
}
boost
介绍
在查询时,可以增加字段的算分,默认为1
请求格式
# 创建索引时候指定
PUT /<index>
{"mappings": {"properties": {"<field>": {"type": "text","boost": 2 }}}
}# 查询时指定
POST _search
{"query": {"match" : {"title": {"query": "quick brown fox","boost": 2}}}
}
注意
- 不提升prefix,range,fuzzy查询的分数
- 不建议使用index time提升。而是在search time时使用
fields
介绍
text字段类型不能被排序和聚合如果要text字段能被排序或聚合可以使用fields
请求格式
PUT /<index>
{"mappings": {"properties": {"<field>": {"type": "text","fields":{"<child_field>":{"type":"keyword"}}}}}
}