共计 9589 个字符,预计需要花费 24 分钟才能阅读完成。
总进度
Elasticsearch 8.1 认证工程师学习路线
明天咱们来学习 Elasticsearch
中的动静模版,其实咱们在第一课 2.2.3 章节中就曾经学过了相似的了,链接如下
依据给定的需要创立索引
然而明天咱们学点不一样的,上次只是简略的应用,这次咱要深刻了解,完满掌控才是第一指标,废话少说,上面开始
什么是动静模版
动静模版容许咱们管制动静字段映射规定之外的数据
动静字段的映射咱们能够设置 dynamic
参数为 true
或者 runtime
来启用动静映射,也能够自定义动静映射模版自定义映射,自定义之后的模版就能够依据匹配规定利用于动静增加的字段。在上一节中,动静映射规定曾经说过,本节间接搬过去,如下
JSON data type |
"dynamic":"true" |
"dynamic":"runtime" |
---|---|---|
null |
不增加 | 不增加 |
true or false |
boolean |
boolean |
double |
float |
double |
long |
long |
long |
object |
object |
不增加 |
array |
依据数组中第一个非空的值判断 | 依据数组中第一个非空的值判断 |
日期类型的字符串 | date |
date |
数字类型的字符串 | float or long |
double or long |
不是日期也不是数字的字符串 | text 类型以及 .keyword 的字类型 |
keyword |
其中自定义动静模版匹配规定形式有如下
match_mapping_type
对Elasticsearch
中检测到的数据类型进行操作,参考上方图表match
与unmatch
能够应用模式匹配字段名path_match
与path_unmatch
对字段的残缺虚线门路进行操作- 如果动静模版没有定义
march_mapping_type
、match
或path_match
,那么模版不会匹配任何一个字段。然而_bulk
申请时能够通过模版名援用模版
也能够应用 {name}
和{dynamic_type}
模版变量作为占位符,比方后文中应用占位符实现分词器的指定等
动静模版的定义是对象数组
"dynamic_templates":[
{
"my_template_name":{#1
... 匹配条件 ...#2
"mapping":{...}#3
}
},
...
]
- 自定义模版名称,能够是任意的字符串
- 模版的应用匹配条件能够是:
match_mapping_type
,match
,match_pattern
,unmatch
,path_match
,path_unmatch
- 匹配字段应该应用的索引映射
通过下面的 学习,咱们晓得了动静模版的定义,既然定义好了就该有验证,毕竟定义好的模版能不能用,是否定义的正确性还是须要验证的
验证动静模版
如果定义的模版蕴含有效的映射片段则会返回谬误。在 index
操作时利用动静模版进行验证,然而大多数状况下在动静模版更新的时候会进行验证。提供有效的映射片段可能造成在更新或者某些条件下动静模版的验证失败,比方:
- 如果没有指定
match_mapping_type
,然而这个模版提供了起码一个的无效映射,那么这个映射片段是无效的。然而如果将与模版匹配的字段映射为其余类型,则在 index 时返回验证谬误。例如:配置一个动静模版,不蕴含match_mapping_type
,这样就是一个无效的字符串类型,然而如果有一个字段匹配动静模版时被匹配为long
,那么在index
时将返回验证谬误。倡议就是将match_mapping_type
配置为预期的JSON
类型(参考结尾的映射关系表)或者在mapping
中配置好所需的类型 - 如果咱们在
mapping
的片段中应用了{name}
占位符,那么在动静模版的更新时是跳过验证的。这是因为过后的字段名还是不晓得的,所以在index
时进行验证
如果有多个模版同时匹配,依照程序匹配规定解决,第一个匹配的模版具备最高的优先级;当通过 update mapping API
更新动静模版时,所有的现有模版将会被笼罩,这就容许在最后的创立动静模版之后能够从新排序或者删除它们
动静模版中映射运行时字段
在上一节中咱们的本大节内容例子就是应用的这个,有趣味的能够回过头再看一眼,链接放到文章结尾了
如果咱们想 Elasticsearch
将某一种类型的新字段动静映射为运行时字段,那么咱们能够通过设置 "dynamic":"runtime"
, 这些字段不会被编入索引,并且在查问时是从_source
加载
或者咱们应用默认的动静映射规定,而后创立动静模版,并将特定的字段映射为运行时字段。咱们须要在 index mapping
中设置 "dynamic:"true",
而后创立一个动静模版,并将某种类型的新字段映射为运行时字段
举个例子,假如咱们有一组数据,其中每个字段都是 _ip
结尾的,依据动静映射规定,Elasticsearch
会依据数值检测到的任何的字符串映射为 float
或者 long
,此时咱们就能够创立一个动静模版,将这个新字符串映射为ip
类型的运行时字段
上面是咱们的一个例子,大略意思就是当 Elasticsearch
应用匹配模式是 ip*
的新字段时,它会将这些字段映射为 ip
类型的运行时字段。因为这些字段不是动静映射的,所以咱们能够应用 "dynamic":"true"
或者 "dynamic":"runtime"
联合应用
PUT my-dynamic-template-001/
{
"mappings": {
"dynamic_templates": [
{
"strings_as_ip": {
"match_mapping_type": "string",
"match": "ip*",
"runtime": {"type": "ip"}
}
}
]
}
}
联合 "dynamic":"true"
或者 "dynamic":"runtime"
应用
PUT my-dynamic-template-001/
{
"mappings": {
"dynamic":"runtime",
"dynamic_templates": [
{
"strings_as_ip": {
"match_mapping_type": "string",
"match": "ip*",
"runtime": {"type": "ip"}
}
}
]
}
}
下面的语句,咱们会把合乎匹配模式 ip*
的新字段映射为运行时字段,然而因为咱们设置 "dynamic":"runtime"
, 所以前面的新字段咱们都会设置为运行时字段,也就是上面这个语句,其中ip_req
,ip_res
, 合乎动静模版dynamic_templates
的匹配规定 ip*
,而my_ip
应用索引结尾设置的 "dynamic":"runtime"
也会退出到运行时字段
PUT my-dynamic-template-001/_doc/1
{
"ip_req":"127.0.0.1",
"ip_res":"127.0.0.1",
"my_ip":"locahost"
}
此时咱们查看索引状况如下
{
"my-dynamic-template-001" : {
"mappings" : {
"dynamic" : "runtime",
"dynamic_templates" : [
{
"strings_as_ip" : {
"match" : "ip*",
"match_mapping_type" : "string",
"runtime" : {"type" : "ip"}
}
}
],
"runtime" : {
"ip_req" : {"type" : "ip"},
"ip_res" : {"type" : "ip"},
"my_ip" : {"type" : "keyword"}
}
}
}
}
下面就是一个简略的应用,其中
match_mapping_type
是string
,也就是字段的值是字符串match
是ip*
即该字段名为ip
结尾的runtime
定义被映射的字段类型,在下面例子中,被映射为runtime
,类型为ip
match_mapping_type
match_mapping_type
是 JSON
解析器检测到的数据类型。因为 JSON
不辨别 long
和integer
,也不辨别 double
和float
,所以解析时 double
和float
都会被认为是 double
,integer
与long
都会被认为是long
留神:当应用动静映射的时候,ELasticsearch 将始终抉择更宽泛的数据类型,然而有个例外是
float
类型,它的须要的存储空间少于double
,并且对于大多数的应用程序来说足够精确。然而运行时字段不反对float
类型,所以这就是"dynamic":"runtime"
应用double
的起因
Elasticsearch 会自动检测数据类型,检测规定就是文章结尾的那个表格内容,并且咱们还能够应用 match_mapping_type
中应用通配符 *
来匹配所有的数据类型
举个例子,如果咱们想把整数字段映射为 integer
而不是 long
类型,字符串字段匹配为 text
和keyword
类型,咱们能够应用如下模版
- 创立一个模版
PUT my-dynamic-template-002
{
"mappings": {
"dynamic_templates": [
{
"integers": {
"match_mapping_type": "long",
"mapping": {"type": "integer"}
}
},
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
}
-
插入一条测试数据
PUT my-dynamic-template-002/_doc/1 { "my_integer": 5, "my_string": "Some string" }
-
查看生成的
mapping
GET my-dynamic-template-002/_mapping
返回后果如下,
my_integer
会被映射为integer
,my_string
会被映射为text
和keyword
{ "my-dynamic-template-002" : { "mappings" : { "dynamic_templates" : [ { "integers" : { "match_mapping_type" : "long", "mapping" : {"type" : "integer"} } }, { "strings" : { "match_mapping_type" : "string", "mapping" : { "fields" : { "raw" : { "ignore_above" : 256, "type" : "keyword" } }, "type" : "text" } } } ], "properties" : { "my_integer" : {"type" : "integer"}, "my_string" : { "type" : "text", "fields" : { "raw" : { "type" : "keyword", "ignore_above" : 256 } } } } } } }
match 与 unmatch
match
应用模式匹配字段名称,unmatch
应用模式排除匹配字段
match_pattern
能够通过设置此参数值调整 match
参数的行为,使 match
参数反对与字段名匹配的残缺 Java
正则表达式来代替简略的通配符,如下
"match_pattern": "regex",
"match": "^profit_\d+$"
如下示例,咱们匹配名称以 long_
结尾的所有字符串字段,排出以 _text
结尾的字符串字段,并将它们映射为 long
类型的字段
PUT my-dynamic-template-003
{
"mappings": {
"dynamic_templates": [
{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "long_*",
"unmatch": "*_text",
"mapping": {"type": "long"}
}
}
]
}
}
PUT my-dynamic-template-003/_doc/1
{
"long_num": "5",
"long_text": "foo"
}
GET my-dynamic-template-003/_mapping
在下面例子中,long_num
被映射为 long
类型的字段,这是因为 match_mapping_type
为string
类型,并且是 long_
结尾的。long_text
尽管是 long_
结尾的,然而也是 _text
结尾的,合乎 unmatch
条件,这样的话 long_text
就依照默认规定 string
进行映射,生成 text
及keyword
字段
path_match 与 path_unmatch
path_match
和 path_unmatch
与match
和 unmatch
原理相似,然而是对字段的残缺虚线门路进行匹配,而不仅仅是最终名称,例如some_object.*.some_field
PUT my-dynamic-template-004
{
"mappings": {
"dynamic_templates": [
{
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
PUT my-dynamic-template-004/_doc/1
{
"name": {
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
}
如上所示,但凡 name
下的任何字段,除了以 middle
结尾的字段除外,都会被映射为 text
类型,并且 copy_to
带有full_name
执行如下命令查看
GET my-dynamic-template-004/_mapping
显示后果如下
{
"my-dynamic-template-004" : {
"mappings" : {
"dynamic_templates" : [
{
"full_name" : {
"path_match" : "name.*",
"path_unmatch" : "*.middle",
"mapping" : {
"copy_to" : "full_name",
"type" : "text"
}
}
}
],
"properties" : {
"full_name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"name" : {
"properties" : {
"first" : {
"type" : "text",
"copy_to" : ["full_name"]
},
"last" : {
"type" : "text",
"copy_to" : ["full_name"]
},
"middle" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
}
}
从下面的后果可知,咱们可能看进去,name
之下的 middle
没有 copy_to
,它的映射依照默认的string
映射规定,生成 text
以及keyword
须要留神的是,除了 leaf
字段外,path_match
与 path_unmatch
参数匹配对象门路,如下对文档索引将产生谬误,因为 name.title
不能映射为文本类型
PUT my-dynamic-template-004/_doc/2
{
"name": {
"first": "Paul",
"last": "McCartney",
"title": {
"value": "Sir",
"category": "order of chivalry"
}
}
}
报错如下
{
"error" : {
"root_cause" : [
{
"type" : "mapper_parsing_exception",
"reason" : "failed to parse field [name.title] of type in document with id'2'. Preview of field's value: '{category=order of chivalry, value=Sir}'"
}
],
"type" : "mapper_parsing_exception",
"reason" : "failed to parse field [name.title] of type in document with id'2'. Preview of field's value: '{category=order of chivalry, value=Sir}'",
"caused_by" : {
"type" : "illegal_state_exception",
"reason" : "Can't get text on a START_OBJECT at 5:14"
}
},
"status" : 400
}
template variables(模版变量)
{name}
和 {dynamic_type}
占位符在映射中被替换为字段名称和检测到的动静类型
如下示例,将所有的字符串字段应用与字段同名的分析器,并禁用所有不是字符串字段的doc_values
PUT my-dynamic-template-005
{
"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-dynamic-template-005/_doc/1
{
"english": "Some English text",
"count": 5
}
GET my-dynamic-template-005/_mapping
在下面例子中,{name}
被替换为 field name
,而{dynamic_type}
被替换为有 JSON
解析器检测到的数据类型
english
字段分析器设置为 english
,而count
被检测为 long
类型,并且 doc_values
设置为false
动静模版的例子
结构化搜寻
当咱们设置 "dynamic":"true"
时,Elasticsearch 会将字符串字段映射为 text
类型,并带有一个 keyword
类型的子字段,如果咱们只是结构化的搜寻,对全文检索不须要,那么咱们就能够让 Elasticsearch 映射为 keyword
字段,然而这样做的话,必须搜寻与索引完全相同的值能力搜寻这些字段,也就是准确匹配
PUT my-dynamic-template-006
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {"type": "keyword"}
}
}
]
}
}
字符串的纯文本映射
与下面结构化搜寻相同,如果咱们只关怀全文检索,并且不会对字段进行聚合、排序和准确查找,那么咱们让 Elasticsearch 将字符串映射为 text
类型
PUT my-dynamic-template-007
{
"mappings": {
"dynamic_templates": [
{
"strings_as_text": {
"match_mapping_type": "string",
"mapping": {"type": "text"}
}
}
]
}
}
对于最近版本减少的运行时字段,咱们呢还能够创立一个动静模版,将字符串映射为运行时的 keyword
类型,虽说该字段不会被索引,然而它们的值是存在 _source
中,并且能够用于搜寻、聚合、过滤和排序
例如如下示例,将创立一个动静模版,将 string
字段映射为 keyword
运行时字段,尽管 runtime
定义是空的,然而 Elasticsearch 会应用文章结尾的匹配规定增加,任何一个未通过工夫或者数字检测的字符串都会被映射为 keyword
类型
PUT my-dynamic-template-008
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"runtime": {}}
}
]
}
}
此时咱们索引一个文档
PUT my-dynamic-template-008/_doc/1
{
"english": "Some English text",
"count": 5
}
查看映射关系时,能够看到 english
被映射为 keyword
类型的运行时字段
GET my-dynamic-template-008/_mapping
{
"my-dynamic-template-008" : {
"mappings" : {
"dynamic_templates" : [
{
"strings_as_keywords" : {
"match_mapping_type" : "string",
"runtime" : {}}
}
],
"runtime" : {
"english" : {"type" : "keyword"}
},
"properties" : {
"count" : {"type" : "long"}
}
}
}
}
Disable norms
如果咱们不依照评分进行排序,那么能够禁用索引中的评分因子以节俭空间
PUT my-dynamic-template-009
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"norms": false,
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
}
下面模版中呈现的 keyword
的关键字字段是与动静映射的默认规定统一的,如果咱们不须要能够依照下面的例子将其删除
工夫序列
在应用 Elasticsearch 进行工夫序列的剖析时,通常会有很多的数字字段,然而这些数字字段个别不会进行过滤通常都是进行聚合。在这种状况下咱们能够禁用这些字段的索引以节俭磁盘空间,或者也可能取得一些索引的速度
PUT my-dynamic-template-010
{
"mappings": {
"dynamic_templates": [
{
"unindexed_longs": {
"match_mapping_type": "long",
"mapping": {
"type": "long",
"index": false
}
}
},
{
"unindexed_doubles": {
"match_mapping_type": "double",
"mapping": {
"type": "float",
"index": false
}
}
}
]
}
}
与默认的动静规定一样,double
被映射为float
,因为他能够满足绝大多数的申请。并且只须要一半的磁盘空间
总结
好了对于动静模版的常识到这就完结了,从开始介绍什么是动静模版,其次是动静模版如何应用以及最初的动静模版的罕用示例,那么你把握了多少呢,快去尝试一下吧,下一篇预报《为工夫序列索引定义索引生命周期策略 ILM》敬请期待
本文由 mdnice 多平台公布