文章目录
Mapping映射介绍
概念:自动或手动为index中的文档建立的一种数据结构和相关配置,称为mapping映射。
如果很难理解,可以把ES中的文档想象成MySQL数据库中的Table表,而映射就是对表中的字段创建对应的数据类型。
一般来说,Mapping映射分为自动映射和手动映射。
自动映射
在第一次在插入数据时,ES自动创建索引,同时也会对插入的数据创建相对应的数据类型和分词器,我们将此称为自动映射。
演示:
-
插入一条数据
-
使用语法
GET /index/_mapping
查询映射。
{
"student" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"birthday" : {
"type" : "date"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
可以看到的是,我们并未对字段的数据类型进行定义,而在ES中,自动将name
定义为了text
,age
定义为了long
,birthday
定义为了date
,这就是ES所提供的自动映射。
手动映射
有时候自动映射的未必是我们想要的,此时可以通过手动设置映射。
创建步骤:
-
创建索引
语法:PUT /index
-
手动创建映射
语法:PUT /index/_mapping
PUT /student/_mapping
{
"properties": {
"name": {
"type": "text"
},
"age":{
"type":"short"
},
"birthdy":{
"type":"date"
},
"description": {
"type": "text",
"analyzer":"english",
"search_analyzer":"english"
}
}
}
- 查询映射类型
此时的age
字段类型改成了short
。
创建映射的格式可以参考上方的格式,在properties
中对字段进行设置,其中description
字段中的analyzer(分词器)会在之后的文章中介绍。
修改映射
对于想要修改映射,只能创建index时手动建立mapping映射,或者新增字段mapping映射,但是不能修改字段的mapping映射。因为已有数据按照映射早已分词存储好,因此无法修改。
新增一个字段mapping:
语法:PUT /index/_mapping
PUT /student/_mapping
{
"properties": {
"hobbys": {
"type": "text"
}
}
}
此时就为student
文档新增了一个hobbys
(把y变i加es,大学英语水平变小学了哈哈哈哈)映射。
删除映射
通过删除索引来删除映射。
语法:DELETE /index
删除操作简单粗暴!!!这里就不做演示了。
ES数据类型
ES和其它的NoSQL数据库一样,支持文档中字段的多种不同数据类型。
这里只对常用的做一些介绍,具体可以参考ES数据类型官方文档。
String类型
Text
Text是用于索引全文值的字段,意思就是例如有一个text类型文本存储了以下内容:杰瑞张的不丑的话也挺帅的
,当搜索杰瑞挺帅的
(扎心了)的时候,就会搜出上面的内容,这就是全文检索。
常用参数:
- analyzer
通过analyzer属性指定分词器。刚才的例子指定了analyzer是指在索引使用english,默认为default index分词器
或standard分析器
。 - index
index属性指定是否索引。默认为true,设为false则不会进行索引,此时搜索无法获取。 - store
是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在_source
中,一般不需要设置为true,因为store文档中已经有一份原始文档了。
Keyword
Keyword目前已经取代了"index": false
。Text文本字段在映射时要设置分词器,keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、 手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。
Number类型
Number字段和大多常见的字段一样。
- long
一个有符号的 64 位整数,最小值为 -263,最大值为263-1。
- integer
一个有符号的 32 位整数,最小值为 -232,最大值为232-1。
- short
一个有符号的 16 位整数,最小值为-32,768,最大值为32,767。
- byte
一个有符号的 8 位整数,最小值为-128,最大值为127。
- double
双精度 64 位 IEEE 754 浮点数,限制为有限值。
- float
单精度 32 位 IEEE 754 浮点数,限制为有限值。
- half_float
半精度 16 位 IEEE 754 浮点数,限制为有限值。
- scaled_float
由 a 支持的浮点数long,按固定double比例因子缩放。
如何更好的使用Number?
- 尽量选择范围小的类型,提高搜索效率。
- 对于浮点数尽量用比例因子,比如一个价格字段,单位为元,我们将比例因子设置为100这在ES中会按照分进行存储,映射如下:
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
例如比例因子为100,假如我们输入的价格是23.45,则ES中会将23.45乘以100,得到2345,然后存储在ES中。
如果输入的价格是23.456,ES会将23.456乘以100再取一个接近原始值的数,得到2346,然后存储在ES中。
前段时间在看一本书叫做《高性能MySQL》,书中写道:在MySQL 5.0和更高版本,DECIMAL类型支持精确计算,对于一些银行金融业务,DECIMAL无疑是最好的选择。但在数据量比较大的时候,可以考虑使用BIGINT代替DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可。假设要存储财务数据精确到万分之一分,则可以把所有金额乘以一百万,然后将结果存储在BIGINT里,这样可以同时避免浮点存储计算不精确和DECIMAL精确计算代价高的问题。
比例因子就和此方法有异曲同工之处。
此外scaling_facto
r是scaled_float
的一个附加参数,其它数字类型不支持。
Date类型
日期类型不用设置分词器,通常日期类型的字段用于排序。
- 常用参数 format
通过format设置日期格式
{
"properties":
{
"timestamp": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
}
}
}
上面的设置允许date字段存储年月日时分秒、年月日及毫秒三种格式。
Object类型
Object类型是通过JSON形式来存储。
例如:
PUT /customer/store/1
{
"address": {
"country": "China",
"province": "zhejiang",
"city": "hangzhou"
},
"name": "jack",
"age": 18,
"birthday": "2021-01-01"
}
Nested类型
和Object类型一样,Nested类型包含了嵌套的表示。
例如:
{
"customers": [
{ "age": 32, "name": "James Harder"},
{ "age": 33, "name": "Stephen Curry"},
{ "age": 33, "name": "Kevin Durant"}
]
}
那么Object和Nested在底层是如何存储的?
上述的Object例子:
{
"name": [jack]
"age": [18]
"birthday": [2021-01-01]
"address.country": [China],
"address.province": [zhejiang],
"address.city": [hangzhou]
}
上述的Nested例子:
{
"customers.age": [32,33,33],
"customers.name": [James,Harder,Stephen,Curry,Kevin,Durant]
}
ES会进行分词然后通过数组的格式进行存储,关于分词,之后会在文章中进行介绍。
感谢阅读!