ElasticSearch笔记-动态映射

介绍

当Elasticsearch在文档中检测到新字段时,会自动确定字段的数据类型,并自动把新字段添加到映射的过程称为动态映射。
如果启用了动态字段映射,Elasticsearch采用一些规则来确定JSON字段对应的数据类型,规则包括动态字段映射(Dynamic field mappings)和动态模板集(Dynamic templates)。

动态参数设置(dynamic)

通过设置参数dynamic,可以在文档和对象级别控制动态映射的行为,dynamic可以有下列三种值:
true:将检测到的新字段自动添加到映射中(默认)
false:忽略检测到的新字段。这些字段不会被索引,因此不能搜索,但仍然会出现在_source字段中。这些字段将不会添加到映射中,新字段必须显式添加
strict:如果检测到新字段,抛出异常。新字段必须显式添加

dynamic设置为strict,并且是类型级别,表示不会动态添加top级字段
user 对象继承类型级别设置
dynamic设置为true,并且是对象级别,表示social_networks对象可以动态添加字段
PUT my_index
{
  "mappings": {
    "dynamic": "strict", // 1
    "properties": { 
      "user": {              // 2
        "properties": {
          "social_networks": { 
            "dynamic": "true", // 3
            "properties": {}
          }
        }
      }
    }
  }
}

动态字段映射规则

JSON数据类型 ES数据类型
true 或 false boolean类型
浮点型数字 double
整型数字 long
JSON对象 Object
数组 第一个非空值得类型
String 1、如果满足日期类型的格式,映射为日期类型(date)
2、如果满足数字型的格式,映射为long或者float
3、如果就是字符串,会映射为一个text类型和一个keyword类型

日期检测(date_detection)

如果启用了date_detection(默认启用),那么将检查新的字符串字段,看它们的内容是否匹配dynamic_date_formats中指定的任何日期模式。如果找到匹配项,将添加相应格式的一个新日期字段。
参数dynamic_date_formats 默认格式为
[ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]
举个例子:

# 创建索引,未指定字段类型
PUT my_index_01/_doc/1
{"create_date":"2015/09/02"}
# 查看索引的映射
GET my_index_01/_mapping 
# 返回结果,表示已经动态映射为日期类型
{
  "my_index_01" : {
    "mappings" : {
      "properties" : {
        "create_date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
        }
      }
    }
  }
}

禁用日期检测
如果禁用了日期检测,那么Elasticsearch遇到日期格式的字符串,会动态映射到其他类型(text或keyword),通过设置参数date_detection等于false来禁用动态日期检测。示例如下:

# 禁用date_detection
PUT my_index_01
{"mappings":{"date_detection":false}}
# 创建索引,未指定字段类型
PUT my_index_01/_doc/1
{"create_date":"2015/09/02"}
# 查看索引的映射
GET my_index_01/_mapping 
# 返回结果,表示已经动态映射为text类型
{
  "my_index_01" : {
    "mappings" : {
      "date_detection" : false,
      "properties" : {
        "create_date" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

自定义检测日期格式
可以自定义动态检测的日期格式。示例如下:

PUT my_index_01
{"mappings":{"dynamic_date_formats":["MM/dd/yyyy"]}}

数字检测(numeric_detection)

虽然JSON支持本地浮点数和整数数据类型,但一些应用程序或语言有时可能将数字呈现为字符串。通常正确的解决方案是显式映射这些字段,但数字检测(默认禁用)可以自动做到这一点,示例如下:

# 开启数字检测
PUT my_index_01
{"mappings":{"numeric_detection":true}}
PUT my_index_01/_doc/1
{"my_float":"1.0","my_integer":"1"}
GET my_index_01/_mapping
{}
# 返回结果,字段 my_float 映射为float类型,字段 my_integer 映射为long类型
{
  "my_index_01" : {
    "mappings" : {
      "numeric_detection" : true,
      "properties" : {
        "my_float" : {
          "type" : "float"
        },
        "my_integer" : {
          "type" : "long"
        }
      }
    }
  }
}

动态模板

又称自定义映射,根据匹配条件应用于动态添加的字段
动态模板集是一个object数组,包含至少一个动态模板,结构示例如下:

# 双斜线在执行时需要去掉
PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [ //1
      {
        "integers": { // 2
          "match_mapping_type": "long", //3
          "mapping": { // 4
            "type": "integer"
          }
        }
      }
    ]
  }
}

注释1-动态模板集参数名为dynamic_templates,固定的。
注释2-动态模板名称自定义。
注释3-匹配条件,包括match_mapping_type, match, match_pattern, unmatch, path_match, path_unmatch。
注释4-匹配字段使用的类型映射。
动态模板集包含几类重要参数:
(1)match_mapping_type作用于检测数据类型。
(2)match和unmatch或match_pattern作用于字段的名称。
(3)path_match和path_unmatch作用于字段的完整点路径。
可以在动态模板集中的映射使用占位符{name}和{dynamic_type}, {name}表示原始字段名,{dynamic_type}表示检测到的数据类型。

match_mapping_type

match_mapping_type对应的值是JSON解析器检测到的数据类型
**星号可以匹配所有数据类型
案例:将所有证书字段映射为integer类型,而不是long类型,将所有字符串映射为text类型和keyword类型

PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "template1": {
          "match_mapping_type": "long",
          "mapping": {
            "type": "integer"
          }
        }
      },
      {
        "template2": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    ]
  }
}

PUT my_index_01/_doc/1
{"my_integer":5,"my_string":"Some string"}

match和unmatch

match参数使用模式对字段名进行匹配,而unmatch使用模式来排除通过match匹配的字段。
例如,匹配所有字段名称以long_开头的字符串字段(排除以_text结尾的),并将它们映射为long字段,可使用以下模板:

PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "longs_as_strings": {
          "match_mapping_type": "string",
          "match": "long_*",
          "unmatch": "*_text",
          "mapping": {
            "type": "long"
          }
        }
      }
    ]
  }
}
PUT my_index_01/_doc/1
{"long_num":"5","long_text":"foo"}

match_pattern

match_pattern参数用来调整match参数的行为,可以在字段名上支持完整的Java正则表达式匹配,例如:

PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "pattern_as_strings": {
          "match_mapping_type": "string",
          "match_pattern": "regex",
          "match": "^long_\\d+$",
          "mapping": {
            "type": "long"
          }
        }
      }
    ]
  }
}
# 字段long_1映射为long类型,字段long_text映射为text或keyword类型
PUT my_index_01/_doc/1
{"long_1":"5","long_text":"foo"}

path_match和path_unmatch

path_match和path_unmatch参数的工作方式与match和unmatch相同,但操作在字段的完整点路径上,而不仅仅是字段名称。
例如:

PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name": {
          "path_match": "name.*",
          "path_unmatch": "*.middle",
          "mapping": {
            "type": "text",
            "copy_to": "full_name"
          }
        }
      }
    ]
  }
}
PUT my_index_01/_doc/1
{"name":{"first":"John","middle":"Winston","last":"Lennon"}}

上面例子将字段名为name的对象中所有子级字段(排除子级middle字段)的值复制到顶层的full_name字段,创建新的字段full_name,复制内容到full_name字段中,但是不会影响_source字段内容。

参考:
https://www.jianshu.com/p/5edfb26af729

posted @ 2021-06-21 21:26  .Neterr  阅读(212)  评论(0编辑  收藏  举报