elasticsearch使用指南之Elasticsearch Dynamic Mapping(动态映射机制)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文详细介绍了elasticsearch的动态类型映射机制,并详细介绍了动态映射模板(Dynamic templates)。

作者简介:《RocketMQ技术内幕》作者、中间件兴趣圈微信公众号维护者

ElasticSearch Mapping(映射)目录:
elasticsearch使用指南之Elasticsearch Mapping类型映射概述与元字段类型

Elasticsearch使用指南之Elasticsearch Mapping parameters(主要参数一览)


Elasticsearch与关系型数据库的另外一个不同就是索引下的的类型中的字段可以动态创建,无需在使用之前先创建好,支持在索引的过程中动态添加。这种机制也得意于Elasticsearch的动态映射机制,能根据字段的值动态猜测字段的类型,从而建立索引映射。
本节将重点介绍Elasticsearch动态映射机制。

PUT data/_doc/1 
{ "count": 5 }

执行上述请求时,索引"data"不必预先创建,该API会首先会自动创建索引data、类型映射_doc,其映射类型下包含字段count,其类型为long。自动为类型映射根据文档的值推测其类型的过程,就是本文要重点描述的机制:动态类型映射机制。动态映射机制包含如下两种映射规则:

  • Dynamic field mappings
  • Dynamic templates

接下来就分别介绍上述两种动态映射规则。

1、Dynamic field mappings
动态字段映射规则。默认情况下,当在文档中发现以前未见过的字段时,Elasticsearch将向类型映射添加新字段。通过将映射参数dynamic 设置为false(忽略新字段)或strict(遇到未知字段时抛出异常),可以在文档和对象级别禁用此行为。

JSON datatype Elasticsearch datatype
null 不会自动增加类型映射
true or false boolean
floating point number float
integer long
object object
array 根据数组中第一个非空值来判断
string date、double、long、text(带有keyword子字段)

1.1 Date detection
日期类型检测,如果启用了date_detection(默认),那么将检查新字符串字段,以查看它们的内容是否匹配dynamic_date_format中指定的任何日期模式。如果匹配其中任意一种格式,则添加字段映射时,字段的类型为date,并指定日期的format为匹配的模式。例如:

PUT my_index/_doc/1
{
  "create_date": "2015/09/02"
}

则会为create_date字段在json中的类型是字符串,但如果date_detection=true,则能映射为date字段。
可以在类型_type级别设置是否开启日期类型检测(date_detection),示例如下:

PUT my_index
{
  "mappings": {
    "_doc": {
      "date_detection": false
    }
  }
}

1.2 定制日期类型检测格式
可以通过类型级别(_type)级别通过dynamic_date_formats参数来自定义日期检测格式,示例如下:

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

PUT my_index/_doc/1
{
  "create_date": "09/25/2015"
}

1.3 numeric detection
数字类型检测。同样如果数字类型的值在JSON中是用字符串表示的话,如果开启日期类型检测,同样在创建映射时会映射为数字类型,而不是字符串类型。

PUT my_index
{
  "mappings": {
    "_doc": {
      "numeric_detection": true
    }
  }
}

默认情况下,numeric_detection为false。

2、Dynamic templates
Dynamic field mappings默认情况下是根据elasticsearch支持的数据类型来推测参数值的类型,而动态模板允许您定义自定义映射规则,根据自定义的规则来推测字段值所属的类型,从而添加字段类型映射。
动态映射模板通过如下方式进行定义:

"dynamic_templates": [      // @1
    {
      "my_template_name": {    // @2
        ...  match conditions ...    // @3
        "mapping": { ... }              // @4
      }
    },
    ...
  ]

代码@1:在类型映射时通过dynamic_templates属性定义动态映射模板,其类型为数组。
代码@2:定义动态映射模板名称。
代码@3:匹配条件,其定义方式包括:match_mapping_type, match, match_pattern, unmatch, path_match, path_unmatch。
代码@4:匹配@3的字段使用的类型映射定义(映射参数为类型映射中支持的参数)

动态类型映射模板的核心关键是匹配条件与类型映射,接下来按照匹配条件定义方式来重点讲解动态类型模板映射机制。

2.1、match_mapping_type
首先使用json解析器解析字段值的类型,由于JSON不能区分long和integer,也不允许区分double和float,所以它总是选择更广泛的数据类型, 例如5,在使用字段动态映射时,elasticsearch会将字段动态映射为long而不是integer类型,那如何将数字5动态映射为integer类型呢,利用match_mapping_type可以实现上述需求,例如,如果希望将所有整数字段映射为整数而不是long,并将所有字符串字段映射为文本和关键字,可以使用以下模板:

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
                }
              }
            }
          }
        }
      ]
    }
  }
}

一言以蔽之,match_mapping_type为字段动态映射(字段类型检测)得出的类型建立一个映射关系,将该类型转换为mapping定义中的类型。

2.2、match and unmatch
match参数使用模式匹配字段名,而unmatch使用模式排除匹配匹配的字段。
match、unmatch示例如下:

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

代码@1:表示该自动映射模板针对的字段为JSON解析器检测字段的类型为string的新增字段。
代码@2:字段名称以long_开头的字段。
代码@3:排除字段名称以_text的字段。
代码@4:符合long_开头的字段,并且不是以_text结尾的字段,如果JSON检测为string类型的新字段,映射为long。
代码@5:long_num,映射类型为long。
代码@6:long_text虽然也满足long_开头,但是以_text结尾,故该字段不会映射为long,而是保留其JSON检测到的类型string,会映射为text字段和keyword多字段(参考字段动态映射机制)。

2.3、match_pattern
使用正则表达式来匹配字段名称。

"dynamic_templates": [
  {
    "longs_as_strings": {
       "match_mapping_type": "string",  
    "match_pattern": "regex",   // @1
       "match": "^profit_\d+$"       // @2
       "mapping": {                                  
           "type": "long"
        }
    }
  }
]

代码@1:设置匹配模式为regex代表java正则表达式
代码@2:java正则表达式

2.4、path_match and path_unmatch
path_match与path_unmatch的工作方式与match、unmatch一样,只不过path_match是针对字段的全路径,特别是针对嵌套类型(object、nested)。
下面一个示例:将name下的字段除了middle字段为copy到name属性并列的full_name字段中。

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "copy_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"
  }
}

2.5、{name} and {dynamic_type}
{name}展位符,表示字段的名称。
{dynamic_type}:JSON解析器解析到的字段类型。

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "named_analyzers": {                           // @1
            "match_mapping_type": "string",
            "match": "*",
            "mapping": {
              "type": "text",
              "analyzer": "{name}"
            }
          }
        },
        {
          "no_doc_values": {                         // @2
            "match_mapping_type":"*",
            "mapping": {
              "type": "{dynamic_type}",
              "doc_values": false
            }
          }
        }
      ]
    }
  }
}

PUT my_index/_doc/1
{
  "english": "Some English text", 
  "count":   5 
}

代码@1:映射模板的含义为:对所有匹配到的字符串类型,类型映射为text,对应的分析器的名称与字段名相同,这个在使用时慎重,可能不存在同名的分析器,本例只是一个展示。
代码@2:对于匹配到的任何类型,其映射定义为类型为自动检测的类型,并且禁用doc_values=false。

本节详细介绍了Elasticsearch动态类型映射机制。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
6月前
|
存储 自然语言处理 数据库
使用Elasticsearch映射定义索引结构
使用Elasticsearch映射定义索引结构
|
5月前
|
自然语言处理 关系型数据库 数据库
ElasticSearch 映射类型及数据类型区分
ElasticSearch 映射类型及数据类型区分
58 0
|
6月前
|
存储 自然语言处理 NoSQL
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之倒排索引(三)
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之倒排索引(三)
|
6月前
|
存储 自然语言处理 关系型数据库
Elasticsearch如何修改Mapping结构并实现业务零停机
Elasticsearch如何修改Mapping结构并实现业务零停机
|
6月前
|
存储 JSON 定位技术
深入理解Elasticsearch的索引映射(mapping)
深入理解Elasticsearch的索引映射(mapping)
|
6月前
|
存储 自然语言处理 NoSQL
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之列存(二)
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之列存(二)
|
6月前
|
存储 JSON NoSQL
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)
|
7月前
|
数据采集 数据挖掘 索引
Elasticsearch “指纹”去重机制,你实践中用到了吗?
Elasticsearch “指纹”去重机制,你实践中用到了吗?
95 7
|
7月前
|
Kubernetes Java 索引
Elasticsearch 源码探究 001——故障探测和恢复机制
Elasticsearch 源码探究 001——故障探测和恢复机制
107 0
|
1月前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
54 5