总进度

Elasticsearch 8.1 认证工程师学习路线

明天咱们来学习Elasticsearch中的动静模版,其实咱们在第一课2.2.3章节中就曾经学过了相似的了,链接如下

依据给定的需要创立索引

然而明天咱们学点不一样的,上次只是简略的应用,这次咱要深刻了解,完满掌控才是第一指标,废话少说,上面开始

什么是动静模版

动静模版容许咱们管制动静字段映射规定之外的数据

动静字段的映射咱们能够设置dynamic参数为true或者runtime来启用动静映射,也能够自定义动静映射模版自定义映射,自定义之后的模版就能够依据匹配规定利用于动静增加的字段。在上一节中,动静映射规定曾经说过,本节间接搬过去,如下

JSON data type"dynamic":"true""dynamic":"runtime"
null不增加不增加
true or falsebooleanboolean
doublefloatdouble
longlonglong
objectobject不增加
array依据数组中第一个非空的值判断依据数组中第一个非空的值判断
日期类型的字符串datedate
数字类型的字符串float or longdouble or long
不是日期也不是数字的字符串text类型以及.keyword的字类型keyword

其中自定义动静模版匹配规定形式有如下

  • match_mapping_typeElasticsearch中检测到的数据类型进行操作,参考上方图表
  • matchunmatch 能够应用模式匹配字段名
  • path_matchpath_unmatch 对字段的残缺虚线门路进行操作
  • 如果动静模版没有定义march_mapping_typematchpath_match,那么模版不会匹配任何一个字段。然而_bulk 申请时能够通过模版名援用模版

也能够应用{name}{dynamic_type}模版变量作为占位符,比方后文中应用占位符实现分词器的指定等

动静模版的定义是对象数组

"dynamic_templates":[  {    "my_template_name":{#1      ... 匹配条件 ...#2      "mapping":{...}#3    }  },  ...]
  1. 自定义模版名称,能够是任意的字符串
  2. 模版的应用匹配条件能够是:match_mapping_type,match,match_pattern,unmatch,path_match,path_unmatch
  3. 匹配字段应该应用的索引映射

通过下面的 学习,咱们晓得了动静模版的定义,既然定义好了就该有验证,毕竟定义好的模版能不能用,是否定义的正确性还是须要验证的

验证动静模版

如果定义的模版蕴含有效的映射片段则会返回谬误。在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_typestring,也就是字段的值是字符串
  • matchip* 即该字段名为ip结尾的
  • runtime 定义被映射的字段类型,在下面例子中,被映射为runtime,类型为ip

match_mapping_type

match_mapping_typeJSON解析器检测到的数据类型。因为JSON不辨别longinteger,也不辨别doublefloat,所以解析时doublefloat都会被认为是doubleintegerlong都会被认为是long

留神:当应用动静映射的时候,ELasticsearch将始终抉择更宽泛的数据类型,然而有个例外是float类型,它的须要的存储空间少于double,并且对于大多数的应用程序来说足够精确。然而运行时字段不反对float类型,所以这就是"dynamic":"runtime"应用double的起因

Elasticsearch 会自动检测数据类型,检测规定就是文章结尾的那个表格内容,并且咱们还能够应用match_mapping_type中应用通配符*来匹配所有的数据类型

举个例子,如果咱们想把整数字段映射为integer而不是long类型,字符串字段匹配为textkeyword类型,咱们能够应用如下模版

  • 创立一个模版
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会被映射为integermy_string会被映射为textkeyword

    {  "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_typestring类型,并且是long_结尾的。long_text尽管是long_结尾的,然而也是_text结尾的,合乎unmatch条件,这样的话long_text就依照默认规定string进行映射,生成textkeyword字段

path_match与path_unmatch

path_matchpath_unmatchmatchunmatch原理相似,然而是对字段的残缺虚线门路进行匹配,而不仅仅是最终名称,例如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_matchpath_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 [text] 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 [text] 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多平台公布