• 【Elasticsearch教程5】Mapping 动态模板 Dynamic templates


    一、前言

    上一篇博客【Elasticsearch教程4】Mapping 动态映射讲的动态映射虽然使用简单,但往往不能满足企业的业务场景。比如:

    • 对于整数,一般用integer就足够了,但是ES会默认成long
    • 对于字符串(邮箱,住址),一般我们不用分词,但是ES总会设成带.keyword子字段的text类型。

    动态模板(Dynamic templates)可以满足我们需求,在创建mapping时,先定义好规则,当新字段满足某条规则时,就会按照该规则的预先配置来创建字段。

    二、动态模板的类型

    ES提供了3个角度来定义规则:

    1. 数据类型(data type)
    2. 字段名称(field name)
    3. 字段全点路径(full dotted path to the field)
    角度匹配语法
    数据类型match_mapping_type
    字段名称match unmatch
    字段全点路径path_matchpath_unmatch

    三、动态模板的语法

    dynamic_templates是一个数组,可以定义多个规则

    {
    	"mappings": {
    		"dynamic_templates": [
        		{
          			"my_template_name": {  	#1 自定义动态模板名称
            		...匹配规则...        	#2 使用match_mapping_type、match、unmatch等等定义规则 
           		 	"mapping": { ... } 		#3 设置符合该规则的mapping配置
            		}
        		}
      		]
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    四、match_mapping_type

    match_mapping_type是按照数据类型匹配的,比数据类型是long,而且我们知道该字段的数据范围是不会超过int时,我们可以设置规则匹配为integer

    4.1 ES动态字段映射

    我们先了解下ES自己根据数据类型创建的字段类型规则:

    JSON数据类型ES数据类型
    null不添加字段
    true / falseboolean
    doublefloat
    longlong
    objectobject
    array根据数组中第一个非null值的类型
    通过日期检测的stringdate
    通过数字检测的stringfloat 或 long
    没有通过上面2个检测的string.keyword子字段的text类型

    4.2 自定义数据类型规则

    创建如下动态模板:longintegerstirngkeyword

    PUT pigg_test
    {
      "mappings": {
        "dynamic_templates": [
          {
            "my_template_long": {
              "match_mapping_type": "long",
              "mapping": {
                "type": "integer"
              }
            }
          },
          {
            "my_template_string": {
              "match_mapping_type": "string",
              "mapping": {
                "type": "keyword"
              }
            }
          }
        ]
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    插入一笔测试数据

    PUT pigg_test/_doc/1
    {
      "name": "亚瑟王",
      "age": 33
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    通过GET pigg_test/_mapping查询发现ES创建的字段类型确实符合上面定义的模板

          "properties" : {
            "age" : {
              "type" : "integer"
            },
            "name" : {
              "type" : "keyword"
            }
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    五、match unmatch

    在企业开发中用的最多的其实还是这个字段名称匹配。

    • match:字段名称匹配某规则
    • unmatch :字段名称不匹配某规则
    • match_pattern:设置为regex,配合match unmatch 使用正则表达式
    • 注意:对于嵌套对象,match unmatch 只作用于最后一级字段名

    比如企业常用动态表单场景,我们不知道一个表有多少字段,也不知道字段的类型,也不知道某字段是否要分词。我们可以做如下约定:

    规则表达式ES类型字段名称案例
    short_开头"match": "short_*"shortshort_age
    int_开头"match": "int_*"integerinteger_people_count
    long_开头"match": "long_*"longlong_click_count
    bin_开头"match": "bin_*"binarybin_head_img
    ip_开头"match": "ip_*"ipip_location
    text_开头,_ik结尾"match": "text_*_ik"textik分词器text_name_ik
    key_开头"match": "key_*"keywordkey_status
    profit_开头,后面至少跟1位数字,则设为keyword"match_pattern": "regex","match": "^profit_\d+$"keywordprodfit_1

    我们先选择其中3个作为测试例子:

    PUT pigg_test
    {   
      "mappings": {
        "dynamic_templates": [
          {
            "string_to_integer": {
              "match_mapping_type": "string",
              "match":   "int_*",
              "mapping": {
                "type": "integer"
              }
            }
          },
          {
            "string_to_long": {
              "match_mapping_type": "string",
              "match":   "long_*",
              "mapping": {
                "type": "long"
              }
            }
          },
          {
            "string_to_text_ik": {
              "match_mapping_type": "string",
              "match":   "text_*_ik*",
              "mapping": {
                "type": "text",
                "analyzer": "ik_max_word"
              }
            }
          }
        ]
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    插入测试数据:

    PUT pigg_test/_doc/1
    {
      "int_age": "18",
      "long_click_count": "100000",
      "text_name_ik": "亚瑟王"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过GET pigg_test/_mapping查询发现ES创建的字段类型确实符合上面定义的模板

    "properties" : {
            "int_age" : {
              "type" : "integer"
            },
            "long_click_count" : {
              "type" : "long"
            },
            "text_name_ik" : {
              "type" : "text",
              "analyzer" : "ik_max_word"
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    六、path_matchpath_unmatch

    • 上面一级说了match unmatch 只作用于最后一级的字段名
    • 对于一个有多层的内嵌对象,可以用path_matchpath_unmatch

    下面设置person.*下除了age都是text类型

    PUT pigg_test
    {
        "mappings":{
            "dynamic_templates":[
                {
                    "test_float":{
                        "path_match":"person.*",
                        "path_unmatch":"*.age",
                        "mapping":{
                            "type":"text"
                        }
                    }
                },
                {
                    "test_float":{
                        "path_match":"*.age",
                        "mapping":{
                            "type":"integer"
                        }
                    }
                }
            ]
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    插入测试数据:

    PUT pigg_test/_doc/1
    {
      "person": {
        "count": "100",
        "age": "100"
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过GET pigg_test/_mapping查询发现ES创建的字段类型确实符合上面定义的模板

    "properties" : {
         "person" : {
              "properties" : {
                "age" : {
                  "type" : "integer"
                },
                "count" : {
                  "type" : "text"
                }
             }
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    七、注意事项

    • 所有null和空数组[]都属于无效的值,不会匹配任务动态模板的规则
    • 匹配规则时,是按照模板的配置顺序依次进行对比的,使用最先匹配到的那个模板
    • unmatch path_unmatch 不能单独使用
    • 动态模板的3中方式中推荐match unmatch
    • 因为 match_mapping_type的过于简单
    • path_match对用户的设计思想要求比较高,嘎子,path_match这水比较深,你把握不住啊!
  • 相关阅读:
    SecureCRT9.1高亮配色设置
    el-table中合并表头的同时,合并列固定(解决办法)+表头合并受fixed的影响合并不成功(解决办法)
    UE4 解决车轮等模型快速旋转时画面模糊
    奉劝那些刚参加工作的学弟学妹们:要想进大厂,这些核心技能是你必须要掌握的!完整学习路线!
    play() failed because the user didn‘t interact with the document优化媒体不能自动播放
    stable diffusion到底是如何工作的
    再拯救一下,语言搞多了总是忘,曲不离口,敲敲基础的fortran77小程序
    窥一斑而知全豹,从五大厂商看MCU国产化的机遇和挑战
    TCP协议调试工具TcpEngine V1.3.0使用教程
    OpenHarmony应用程序包整体说明
  • 原文地址:https://blog.csdn.net/winterking3/article/details/126522542