• 【ES实战】索引mapping的动态设置


    动态mapping


    fieldmapping类型在使用之前不需要定义。由于有了动态映射,在向索引写入数据的时候,就可以自动添加新的字段名。新字段可以添加到顶级映射类型中,也可以添加到内部对象和嵌套字段中。

    mapping下的dynamic配置项控制是否可以动态添加新字段。它接受三种设置:

    • true
      将新检测到的字段添加到映射中。 (default)
    • false
      新检测到的字段将被忽略。这些字段不会被索引,因此不能被搜索,但仍然会出现在返回的命中的_source字段中。这些字段不会被添加到映射中,新字段必须显式添加。
    • strict
      如果检测到新字段,则抛出异常并拒绝文档。新字段必须显式添加到映射中。

    也就是说在使用动态mapping的前提就是需要将dynamic配置项采用默认项。

    PUT my_index20221022001
    {
        "mappings": {
            "_doc": {
                "dynamic": "strict",
                "properties": {
                    "age": {
                        "type": "text"
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    动态模板允许在一定规则下进行自定义映射。可以配置动态映射规则来定制用于新字段的映射。对于已经存在配置好的字段,不生效。

    动态mapping规则

    动态模板允许基于下列规则将你定义自定义映射应用到动态添加的字段:

    • Elasticsearch检测到的数据类型,与match_mapping_type

    • 字段名称,用matchunmatchmatch_pattern

    • 字段的完整带点路径,并带有path_matchpath_unmatch

    原始字段名{name}和检测到的数据类型{dynamic_type}。模板变量可以作为占位符在映射规范中使用。

    只有当一个字段包含一个具体的值时,动态字段映射才会被添加,而不是空或空数组。这意味着,如果在动态模板中使用null_value选项,它将只在第一个有具体值的字段的文档被索引后才被应用。

    语法规则

    动态模板被指定为一个命名对象的数组。

    "dynamic_templates": [
        {
          "my_template_name": {  // 模板名称可以是任何字符串值。
            ...  match conditions ... // 匹配条件可以包括以下任何一项:match_mapping_type, match, match_pattern, unmatch, path_match, path_unmatch。
            "mapping": { ... } // 匹配字段应使用的映射。
          }
        },
        ...
      ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    模板是按顺序处理的,第一个匹配的模板获胜。当通过put mapping API放入新的动态模板时,所有现有的模板都被覆盖。这允许动态模板在最初添加后被重新排序或删除。

    match_mapping_type

    match_mapping_type是由json解析器检测到的数据类型。由于JSON不允许区分长数和整数或双数和浮点数,它将总是选择更广泛的数据类型,即长数用于整数,双数用于浮点数。

    以下数据类型可以被自动检测到:

    • boolean :当遇到truefalse时,字段的类型为 boolean
    • date :当日期检测被启用并且发现一个字符串与任何配置的日期格式相匹配时,这个字段被设置成date
    • double :当数据拥有小数部分,字段类型为double
    • long :没有小数部分的数字,字段类型为long
    • objectobject表示对象,也叫哈希。
    • stringstring用于字符串。

    *,可以理解为通配符,也可以用来匹配所有数据类型。

    例如,如果我们想把所有的整数字段映射为integer而不是long,把所有的string字段映射为textkeyword,我们可以使用以下模板。

    PUT my_index
    {
      "mappings": {
        "_doc": {
          "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_index/_doc/1
    {
      "my_integer": 5, // my_integer字段被映射为一个整数。
      "my_string": "Some string" // my_string字段被映射为一个text,有一个keywords的多字段。
    }
    
    • 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
    • 36
    • 37
    • 38
    match and unmatch

    参数match使用一个模式来匹配字段名,而unmatch使用一个模式来排除match匹配的字段。

    下面的例子匹配所有名称以long_开头的string字段(以_text结尾的字段除外),并将它们映射为long字段。

    PUT my_index
    {
      "mappings": {
        "_doc": {
          "dynamic_templates": [
            {
              "longs_as_strings": {
                "match_mapping_type": "string",
                "match":   "long_*",
                "unmatch": "*_text",
                "mapping": {
                  "type": "long"
                }
              }
            }
          ]
        }
      }
    }
    
    PUT my_index/_doc/1
    {
      "long_num": "5", //long_num字段被映射为一个long。
      "long_text": "foo" //long_text字段使用默认的字符串映射。
    }
    
    • 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
    match_pattern

    match_pattern参数调整了match参数的行为,例如,它支持字段名上的完整Java正则表达式匹配,而不是简单的通配符。

      "match_pattern": "regex",
      "match": "^profit_\d+$"
    
    • 1
    • 2
    path_match and path_unmatch

    path_matchpath_unmatch参数的工作方式与matchunmatch相同,但对字段的完整点状路径进行操作,而不仅仅是最终名称,例如:some_object.*.some_field

    这个例子将name对象中的任何字段的值复制到顶层的full_name字段,除了middle字段。

    PUT my_index
    {
      "mappings": {
        "_doc": {
          "dynamic_templates": [
            {
              "full_name": {
                "path_match":   "name.*",
                "path_unmatch": "*.middle",
                "mapping": {
                  "type":       "text",
                  "copy_to":    "full_name"
                }
              }
            }
          ]
        }
      }
    }
    
    PUT my_index/_doc/1
    {
      "name": {
        "first":  "Alice",
        "middle": "Mary",
        "last":   "White"
      }
    }
    
    • 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
    {name} and {dynamic_type}

    {name}{dynamic_type}占位符在mapping中被替换成字段名和检测到的动态类型。下面的例子将所有字符串字段设置为使用与字段名称相同的analyzer,并对所有非字符串字段禁用doc_values

    PUT my_index
    {
      "mappings": {
        "_doc": {
          "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", // The english field is mapped as a string field with the english analyzer.
      "count":   5  // 在禁用doc_values的情况下,count字段被映射为一个长字段。.
    }
    
    • 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

    使用场景

    只进行全文检索

    如果字符串字段只进行全文搜索,不打算在字符串字段上运行聚合、排序或精确搜索,可以告诉Elasticsearch只把它映射为一个文本字段(这是5.0之前的默认行为)。

    PUT my_index
    {
     "mappings": {
       "_doc": {
         "dynamic_templates": [
           {
             "strings_as_text": {
               "match_mapping_type": "string",
               "mapping": {
                 "type": "text"
               }
             }
           }
         ]
       }
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    不考虑检索评分情况

    Norms 是索引时的评分因素。如果你不关心评分,例如,如果你从不按分数对文件进行排序,你可以在索引中禁用这些评分因素的存储,以节省一些空间。

    PUT my_index
    {
      "mappings": {
        "_doc": {
          "dynamic_templates": [
            {
              "strings_as_keywords": {
                "match_mapping_type": "string",
                "mapping": {
                  "type": "text",
                  "norms": false,
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    keyword字段出现在这个模板中是为了与动态映射的默认规则一致。当然,如果你不需要它们,因为你不需要对这个字段进行精确的搜索或聚合,可以把它删除。

    时序数据

    在使用Elasticsearch进行时间序列分析时,通常会有许多数字字段,你会经常对这些字段进行汇总,但从不进行过滤。在这种情况下,你可以禁用这些字段的索引,以节省磁盘空间,也可能获得一些索引速度。主要应用是监控类型场景。

    PUT my_index
    {
      "mappings": {
        "_doc": {
          "dynamic_templates": [
            {
              "unindexed_longs": {
                "match_mapping_type": "long",
                "mapping": {
                  "type": "long",
                  "index": false
                }
              }
            },
            {
              "unindexed_doubles": {
                "match_mapping_type": "double",
                "mapping": {
                  "type": "float", // 像默认的动态映射规则一样,双数被映射为浮点数,通常足够精确,但需要一半的磁盘空间。
                  "index": false
                }
              }
            }
          ]
        }
      }
    }
    
    • 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

    英文原文

  • 相关阅读:
    spark性能调优 | 内存优化
    Java数学工具类Math的Math.round()方法
    chatgpt赋能python:Python文件复制到指定文件夹——实现简单又高效的文件操作
    Codeforces Round #804 (Div. 2) - A, B, C
    微信小程序--云开发
    16种最好的方法,你可以推动过去的拖延
    tx.origin 与 msg.sender
    【单片机】独立看门狗IWDG初始化
    广工电工与电子技术实验报告-8路彩灯循环控制电路
    Resin反序列化链分析
  • 原文地址:https://blog.csdn.net/weixin_43820556/article/details/127452636