ElasticSearch索引模板

索引模板

简介

在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总会使用适用范围更广的类型。

  • date,通过上文日期类型检测出来的日期类型。
  • boolean,true or false
  • long,整数类型
  • double,浮点数类型
  • string,字符串类型
  • object,对象类型
  • *用来匹配所有类型

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容