elasticsearch 动态模板
es模板:新建索引不用重新写语句,按照某个模板自动生成对应的属性
功能:可以实现索引分区,比如按照一个月生成一个对应的索引,把每个月的数据放入到对应的月份索引中,避免单个索引过大的问题
本文主要是动态模板的使用说明,不涉及其中的原理实现,另外本文演示的es的版本是 5.4
一、索引模板
下面是新建一个名称为: alibaba_temp
的模板,匹配的规则是按照 alibaba_taobao~
开头, 默认的type是 taobao
,默认生成字段 userId
和 createTm
,并给新建的索引新的别名为 alibaba_taobao
PUT /_template/alibaba_temp
{
"order": 0,
"template": "alibaba_taobao~*",
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1",
"refresh_interval": "5s"
}
},
"mappings": {
"taobao": {
"properties": {
"userId": {
"type": "keyword"
},
"createTm": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
},
"aliases": {
"alibaba_taobao": {}
}
}
当执行完上面语句,并不会产生索引
当我们插入一条数据,而且是索引不存在的索引后
POST /alibaba_taobao~2021-01/taobao/1234567
{
"userId" : "tb323292154345"
}
结果如下图,可以发现alibaba_taobao
有数据,同样alibaba_taobao~2021-01
也是有数据的,不截图了。
我们看下alibaba_taobao
的定义,如下图:可以发现,有两个字段,就是模板定义的两个字段,说明是使用模板建设索引的,这也就完成了模板的任务。
二、分区
这里所说的分区是指把大索引拆成小索引,避免单个索引过大的问题。
例如我们的业务一个月就要新建一个索引,把新月份产生的数据写入到新的索引中。
例如我们新插入一条数据
POST /alibaba_taobao~2021-02/taobao/888888
{
"userId" : "tb8888888"
}
可以发现:索引alibaba_taobao
里有两条数据,但是是在不同的index
中,也就是不同的业务数据落入不同的索引中。
问题:我们查询需要加上对应的日期吗?当然不用,因为我们查询的时候,并不知道数据插入到哪个分区的,这就是我们使用别名的作用,当然也可以按照条件查询。
这里要注意的问题是要根据自己的业务情况,确定一个id只能落入一个分区中,保证数据的完整性,否则对查询是不友好的,比如上面的例子要根据用户注册的时间确定所在的分区,当用户更新信息时候,要从es中获取原来的注册时间,重新更新到原来的索引中。
三、模板的操作
- 查看某个模板
GET _template/alibaba_temp - 删除某个模板
DELETE _template/alibaba_temp - 更新某个模板:和新建模板一样,重新执行一遍
注意:更新模板后,不会对原来使用该模板的索引产生影响,也就是说原来的索引的字段和字段类型还是原来的模板,新的模板特性不会应用。
如果想对原来的索引也要添加新特性,只能通过手动更改原来索引,注意接口可能有空指针异常
下面是更新模板的具体验证:更新后的目标多了一个addr
字段
PUT /_template/alibaba_temp
{
"order": 0,
"template": "alibaba_taobao~*",
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1",
"refresh_interval": "5s"
}
},
"mappings": {
"taobao":{
"properties": {
"userId": {
"type": "keyword"
},
"addr": {
"type": "keyword"
},
"createTm": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
},
"aliases": {
"alibaba_taobao": {}
}
}
当我们在原来的索引上新增一条数据
POST /alibaba_taobao~2021-01/taobao/11111
{
"addr" : "tb11111"
}
结果如下:可以发现,该索引的定义的字段addr
是text
,而不是keyword
说明原来的索引并不会使用新模板的特性。
- 当匹配到多个模板时候,将综合多个模板的结果生成索引,可以为各个模板设置order值,大的值将覆盖小的值的模板字段。
四、动态模板(dynamic_templates)
通过上面的过程我们发现一个痛点:模板不利于以后扩展,不能每次新增字段都要更新一次模板吧,这样风险也很大,有没有其他的解决方案呢?当然有这就是动态模板,动态模板主要是根据规则自动把字段设置成对应类型,不用手动更新。所以说动态模板主要是设置mapping中字段是怎么识别对应的类型的。
动态模板是为某一个索引服务的。
比如下面的动态模板都是为alibaba_taobao~
开头的索引服务的。
下面是动态模板的例子:
PUT /_template/alibaba_temp
{
"order": 0,
"template": "alibaba_taobao~*",
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1",
"refresh_interval": "5s"
}
},
"mappings": {
"taobao": {
"dynamic_templates": [
{
"string_as_date": {
"match_mapping_type": "string",
"match": "*Tm",
"mapping": {
"type": “date”,
"format": "yyyy-MM-dd HH:mm:ss"
}
}
},
{
"string_as_num": {
"match_mapping_type": "string",
"match": “*Num",
"mapping": {
"type": “integer"
}
}
},
{
"string_as_boolean": {
"match_mapping_type": "boolean",
"match": "is*",
"mapping": {
"type": "boolean"
}
}
},
{
"string_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
],
"properties": {
"userId": {
"type": "keyword"
},
"createTm": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
},
"aliases": {
"alibaba_taobao": {}
}
}
字段说明: string_as_boolean
规则名称
上面的语句构建了 4个规则:
- 把值是string,字段以Tm结尾的转成date
- 把值是string,字段以Num结尾的 转成integer
- 把值是string,is开头的字段,都设为 boolean形式(当然里面的值必须是“true”,“false” 否则按照默认识别)
- 把值是string 转成 keyword
插入如下语句(先删掉原来索引)
POST /alibaba_taobao~2021-01/taobao/11111
{
"userId" : "tb11111",
"createTm" : "2021-01-30 17:00:00",
"addr" : "shenzhen,guangdong",
"isOnline" : "true",
"ageNum": "30",
"numStr" : 100,
"updateTm" : "2021-01-30 17:10:00"
}
则alibaba_taobao~2021-01
对应的索引定义如下图
注意:关于规则是有优先级的
- 如果有直接定义该变量,则优先级最高
- 如果有定义动态模板,如果有对应的规则,则按照规则确定
- 如果动态模板有多个规则匹配,则按照先后顺序确定,先匹配到先获胜
- 如果都没有,则按照默认的方式确定
如果上面的动态模板中
string_as_keyword
和string_as_date
换位置,则所有的值是string的字段,他们的值都是keyword
动态模板中重要的参数说明:
match_mapping_type
es默认认为字段值的类型,match
匹配字段名规则unmatch
与match
相反match_pattern
使用正在表达式,值为"regex",配合match一起使用path_match
与path_unmatch
主要用于嵌套字段配置(没有测试)
1.索引模板是为索引服务的,动态模板是为某个特定索引服务的(可以看到动态模板是定义在mapping中的,是和properties同级别的)。
2.索引模板主要是设置索引的settngs属性,当然也是可以设置mapping的属性,当然索引模板也是可以添加动态模板。
3.动态模板主要是设置mapping中各个字段映射的功能。
4.索引模板中可以放入动态模板,这也是最常用的方式。
上面的内容见:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/dynamic-templates.html#dynamic-templates