ElasticSearch索引模板

2020-03-14  本文已影响0人  饿虎嗷呜

索引模板

简介

在ElasticSearch中创建索引时,可以为创建的索引指定索引的属性设定,映射关系,别名等操作,然而,每次创建索引都要指定这些参数比较麻烦。ES提供了一种方法可以在索引创建时自动为索引进行设置,这种方法叫做索引模板。

索引模板设置

PUT _template/test_temp
{
  "index_patterns": [
    "test*",
    "test-*"
  ],
  "order" : 0,
  "version": 123,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "dynamic": "true",
    "_source": {
      "enabled": "true"
    },
    "properties": {
      "name": {
        "type": "text"
      },
      "High": {
        "type": "integer"
      }
    }
  },
  "aliases": {
    "test-aliases": {}
  }
}

上面这段是使用ES RestAPI创建索引模板:

index_patterns:用来指定适用于该模板的索引名称,一般可以使用前缀加*的方法来进行设定。可以设置多个。

order:可以同时指定多个模板,在存在冲突的情况下,order值高的可以覆盖order值低的模板。如果order值相同,则情况不可预测。

setting,mapping,aliases:与索引设定中的一致。

version:可以选择为索引模板添加版本号。

多模板匹配

ES中存在多个模板匹配到同一个索引的情况。这时候,产生的索引会将两者的配置合并产生新的索引设置内容。如果存在内容冲突的情况,使用order值进行解决,详情见上一节的描述。

以下面为例:

PUT _template/test_temp1
{
  "index_patterns": [
    "test*",
    "test-*"
  ],
  "order" : 1,
  "version": 123,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "dynamic": "true",
    "_source": {
      "enabled": "true"
    },
    "properties": {
      "name": {
        "type": "text"
      },
      "High": {
        "type": "text"
      },
      "weight": {
        "type": "text"
      }
    }
  },
  "aliases": {
    "test-aliases": {}
  }
}

创建一个新的索引:

PUT test2223
GET test2223

{
  "test2223" : {
    "aliases" : {
      "test-aliases" : { }
    },
    "mappings" : {
      "dynamic" : "true",
      "properties" : {
        "High" : {
          "type" : "text"
        },
        "name" : {
          "type" : "text"
        },
        "weight" : {
          "type" : "text"
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1584187147229",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "7T4nlZ8tSteXgju88nR9LQ",
        "version" : {
          "created" : "7040299"
        },
        "provided_name" : "test2223"
      }
    }
  }
}

结果可见,High的类型被覆盖成了text类型。

如果将test_temp1的order值调成0会怎么样呢。笔者试了很多次,High的值一直保持integer的类型。而文档中描述这种情况是不可预知的。

动态字段映射

当一个事先未设置的字段被加入到一个索引中时,ES会怎样处理呢?索引提供了dynamic字段来提供不同的处理策略。dynamic字段有3个可选值,true,false以及strict

true: 这是dynamic字段的默认值,在这种情况,ES会接收字段并根据其类型进行自动映射。

JSON类型 ES类型
null 不做映射
true或者false boolean类型
浮点数字 float类型
integer long类型
object object类型,见:https://www.elastic.co/guide/en/elasticsearch/reference/7.2/object.html
array 取决于数字中第一个非null元素,见:https://www.elastic.co/guide/en/elasticsearch/reference/7.2/array.html
string 如果通过日期类型检测,会被设置成date类型。如果通过数字或者浮点数检测,会被设置成float或者long类型。其他情况,会被识别成text类型,同时会插入一个keyword子类型。

false: 这个字段关闭了动态mapping的功能,如果文档中包含没有事先mapping的字段,这个字段会被存储,但是在搜索时是无法被搜索到的。我们可以通过修改mapping,然后使用_update_by_query API,使得该字段可以被索引到。

strict: 严格mapping,如果有不符合映射关系的字段,索引操作会失败。

日期类型检测

上文提到,ES检测到字符串类型时会自动对其进行日期类型检测。这个行为可以在索引mapping中开启或关闭,默认是处于开启状态。可以通过将date_detection设置成false来将该功能关闭。

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

日期类型检测默认会匹配这样的日期格式:"yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"

用户也可以在dynamic_date_formats中自定义日期格式。

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

数字类型检测

有一些程序会在json格式中将数字类型设置成字符串,ES可以对其进行自动识别,但是该功能默认是关闭的,需要用户手动打开。

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

动态模板

ES还提供了动态模板这种方法来对动态识别出来的字段进行处理。

动态模板的格式如下:

  "dynamic_templates": [
    {
      "my_template_name": { 
        ...  match conditions ... 
        "mapping": { ... } 
      }
    },
    ...
  ]

其中,模板的名称可以自定义,mapping部分则是对动态识别出来的字段进行处理。两种之间则是用来定义进行mapping的条件。这部分可能用到match_mapping_type,match,unmatch,match_pattern,path_match,path_unmatch

动态模板是按顺序进行匹配的,当一个类型命中了一个模板的条件后,就不会再进行后续匹配了。

在模板已经设置的情况下,如果使用put方法设置动态模板。新的模板会覆盖原有模板。

match_mapping_type

match_mapping_type是指的ES的json解析器解析出来的类型,由于json类型不会告诉ES一个整形类型的长度是32位还是64位,也不会告诉ES一个浮点数是单精度还是双精度,因此ES总会使用适用范围更广的类型。

match 和 unmatch

用来做字段名匹配的,match用来指定需要匹配的字段模式,而unmatch则用来将match中包含的部分不需要做动态匹配的字段剔除。

PUT my_index
{
  "mappings": {
    "dynamic_templates": [
      {
        "longs_as_strings": {
          "match_mapping_type": "string",
          "match":   "long_*",
          "unmatch": "*_text",
          "mapping": {
            "type": "long"
          }
        }
      }
    ]
  }
}

以上这段会做以下动作:将未事先指定的字符串类型自动,如果其字段名前缀是long_,且后缀为_text,将其映射为long类型。

match_pattern

match_pattern可以用来指定match的匹配方式,可以指定其为regex,这样就会以java正则匹配的方式来对字段名进行匹配。如果不指定,默认会使用简单的wildchart方式进行匹配。

"match_pattern": "regex",
 "match": "^profit_\d+$"

path_match 和 path_unmatch

matchunmatch类似,区别是path_matchpath_unmatch匹配的的模式是xxx.xxx.xxx,这种模式用于object属性的映射匹配。

PUT my_index
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name": {
          "path_match":   "name.*",
          "path_unmatch": "*.middle",
          "mapping": {
            "type":       "text",
            "copy_to":    "full_name"
          }
        }
      }
    ]
  }
}

PUT my_index/_doc/1
{
  "name": {
    "first":  "John",
    "middle": "Winston",
    "last":   "Lennon"
  }
}

以上将一个人的first name和last name进行组合拼成了一个全名。

内置属性

动态模板有两个内置属性{name}{dynamic_type}用来指代字段名称及其自动识别出来的类型。

PUT my_index
{
  "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_index/_doc/1
{
  "english": "Some English text", 
  "count":   5 
}

以上这段,将识别出来的字符串类型的分词器设置成与其属性名相同。并且关闭了除此之外所有属性的doc_values

上一篇下一篇

猜你喜欢

热点阅读