ElasticSearch索引模板
索引模板
简介
在ElasticSearch中创建索引时,可以为创建的索引指定索引的属性设定,映射关系,别名等操作,然而,每次创建索引都要指定这些参数比较麻烦。ES提供了一种方法可以在索引创建时自动为索引进行设置,这种方法叫做索引模板。
索引模板设置
PUT _template/test_temp
{
"index_patterns": [
"test*",
"test-*"
],
"order" : 0,
"version": 123,
"settings": {
"number_of_shards": 1
},
"mappings": {
"dynamic": "true",
"_source": {
"enabled": "true"
},
"properties": {
"name": {
"type": "text"
},
"High": {
"type": "integer"
}
}
},
"aliases": {
"test-aliases": {}
}
}
上面这段是使用ES RestAPI创建索引模板:
index_patterns
:用来指定适用于该模板的索引名称,一般可以使用前缀加*
的方法来进行设定。可以设置多个。
order
:可以同时指定多个模板,在存在冲突的情况下,order值高的可以覆盖order值低的模板。如果order
值相同,则情况不可预测。
setting
,mapping
,aliases
:与索引设定中的一致。
version
:可以选择为索引模板添加版本号。
多模板匹配
ES中存在多个模板匹配到同一个索引的情况。这时候,产生的索引会将两者的配置合并产生新的索引设置内容。如果存在内容冲突的情况,使用order
值进行解决,详情见上一节的描述。
以下面为例:
PUT _template/test_temp1
{
"index_patterns": [
"test*",
"test-*"
],
"order" : 1,
"version": 123,
"settings": {
"number_of_shards": 1
},
"mappings": {
"dynamic": "true",
"_source": {
"enabled": "true"
},
"properties": {
"name": {
"type": "text"
},
"High": {
"type": "text"
},
"weight": {
"type": "text"
}
}
},
"aliases": {
"test-aliases": {}
}
}
创建一个新的索引:
PUT test2223
GET test2223
{
"test2223" : {
"aliases" : {
"test-aliases" : { }
},
"mappings" : {
"dynamic" : "true",
"properties" : {
"High" : {
"type" : "text"
},
"name" : {
"type" : "text"
},
"weight" : {
"type" : "text"
}
}
},
"settings" : {
"index" : {
"creation_date" : "1584187147229",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "7T4nlZ8tSteXgju88nR9LQ",
"version" : {
"created" : "7040299"
},
"provided_name" : "test2223"
}
}
}
}
结果可见,High
的类型被覆盖成了text
类型。
如果将test_temp1的order
值调成0会怎么样呢。笔者试了很多次,High
的值一直保持integer
的类型。而文档中描述这种情况是不可预知的。
动态字段映射
当一个事先未设置的字段被加入到一个索引中时,ES会怎样处理呢?索引提供了dynamic
字段来提供不同的处理策略。dynamic
字段有3个可选值,true
,false
以及strict
true
: 这是dynamic
字段的默认值,在这种情况,ES会接收字段并根据其类型进行自动映射。
JSON类型 | ES类型 |
---|---|
null | 不做映射 |
true 或者false
|
boolean类型 |
浮点数字 | float类型 |
integer | long类型 |
object | object类型,见:https://www.elastic.co/guide/en/elasticsearch/reference/7.2/object.html |
array | 取决于数字中第一个非null元素,见:https://www.elastic.co/guide/en/elasticsearch/reference/7.2/array.html |
string | 如果通过日期类型检测,会被设置成date类型。如果通过数字或者浮点数检测,会被设置成float或者long类型。其他情况,会被识别成text类型,同时会插入一个keyword子类型。 |
false
: 这个字段关闭了动态mapping的功能,如果文档中包含没有事先mapping的字段,这个字段会被存储,但是在搜索时是无法被搜索到的。我们可以通过修改mapping,然后使用_update_by_query
API,使得该字段可以被索引到。
strict
: 严格mapping,如果有不符合映射关系的字段,索引操作会失败。
日期类型检测
上文提到,ES检测到字符串类型时会自动对其进行日期类型检测。这个行为可以在索引mapping中开启或关闭,默认是处于开启状态。可以通过将date_detection
设置成false
来将该功能关闭。
PUT my_index
{
"mappings": {
"date_detection": false
}
}
日期类型检测默认会匹配这样的日期格式:"yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"
用户也可以在dynamic_date_formats
中自定义日期格式。
PUT my_index
{
"mappings": {
"dynamic_date_formats": ["MM/dd/yyyy", "yyyy/MM/dd"]
}
}
数字类型检测
有一些程序会在json格式中将数字类型设置成字符串,ES可以对其进行自动识别,但是该功能默认是关闭的,需要用户手动打开。
PUT my_index
{
"mappings": {
"numeric_detection": true
}
}
动态模板
ES还提供了动态模板这种方法来对动态识别出来的字段进行处理。
动态模板的格式如下:
"dynamic_templates": [
{
"my_template_name": {
... match conditions ...
"mapping": { ... }
}
},
...
]
其中,模板的名称可以自定义,mapping
部分则是对动态识别出来的字段进行处理。两种之间则是用来定义进行mapping的条件。这部分可能用到match_mapping_type
,match
,unmatch
,match_pattern
,path_match
,path_unmatch
。
动态模板是按顺序进行匹配的,当一个类型命中了一个模板的条件后,就不会再进行后续匹配了。
在模板已经设置的情况下,如果使用put方法设置动态模板。新的模板会覆盖原有模板。
match_mapping_type
match_mapping_type
是指的ES的json解析器解析出来的类型,由于json类型不会告诉ES一个整形类型的长度是32位还是64位,也不会告诉ES一个浮点数是单精度还是双精度,因此ES总会使用适用范围更广的类型。
-
date
,通过上文日期类型检测出来的日期类型。 -
boolean
,true or false -
long
,整数类型 -
double
,浮点数类型 -
string
,字符串类型 -
object
,对象类型 -
*
用来匹配所有类型
match 和 unmatch
用来做字段名匹配的,match
用来指定需要匹配的字段模式,而unmatch
则用来将match
中包含的部分不需要做动态匹配的字段剔除。
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "long_*",
"unmatch": "*_text",
"mapping": {
"type": "long"
}
}
}
]
}
}
以上这段会做以下动作:将未事先指定的字符串类型自动,如果其字段名前缀是long_
,且后缀为_text
,将其映射为long
类型。
match_pattern
match_pattern
可以用来指定match的匹配方式,可以指定其为regex
,这样就会以java正则匹配的方式来对字段名进行匹配。如果不指定,默认会使用简单的wildchart
方式进行匹配。
"match_pattern": "regex",
"match": "^profit_\d+$"
path_match 和 path_unmatch
与match
及unmatch
类似,区别是path_match
和path_unmatch
匹配的的模式是xxx.xxx.xxx,这种模式用于object属性的映射匹配。
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
PUT my_index/_doc/1
{
"name": {
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
}
以上将一个人的first name和last name进行组合拼成了一个全名。
内置属性
动态模板有两个内置属性{name}
和{dynamic_type}
用来指代字段名称及其自动识别出来的类型。
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"named_analyzers": {
"match_mapping_type": "string",
"match": "*",
"mapping": {
"type": "text",
"analyzer": "{name}"
}
}
},
{
"no_doc_values": {
"match_mapping_type":"*",
"mapping": {
"type": "{dynamic_type}",
"doc_values": false
}
}
}
]
}
}
PUT my_index/_doc/1
{
"english": "Some English text",
"count": 5
}
以上这段,将识别出来的字符串类型的分词器设置成与其属性名相同。并且关闭了除此之外所有属性的doc_values
。