查看原文
其他

Elasticsearch Index Templates(索引模板)

丁威 中间件兴趣圈 2022-11-10

索引模板,故名思议,就是创建索引的模板,模板中包含公共的配置(settings)和映射(Mapping),并包含一个简单触发条件,及条件满足时使用该模板创建一个新的索引。

注意:模板只在创建索引时应用。更改模板不会对现有索引产生影响。当使用create index API时,作为create index调用的一部分定义的设置/映射将优先于模板中定义的任何匹配设置/映射。

一个索引模板示例如下:

1PUT _template/template_1
2{
3  "index_patterns": [“ubi*”],                //@1
4  "settings": {                                               //@2 
5    "number_of_shards"1
6  },
7  "mappings": {                                             //@3
8    "_doc": {
9      "_source": {
10        "enabled"false
11      },
12      "properties": {
13        "host_name": {
14          "type""keyword"
15        },
16        "created_at": {
17          "type""date",
18          "format"""
19        }
20      }
21    }
22  }
23}

代码@1:触发条件。
代码@2:索引配置定义。
代码@3:索引映射配置。

上述示例对应的JAVA示例如下:

1public static final void createIndexTemp() {
2        RestHighLevelClient client = EsClient.getClient();
3        try {
4            PutIndexTemplateRequest request = new PutIndexTemplateRequest("ubi_index_template")
5            List<String> indexPatterns = new ArrayList<String>();
6            indexPatterns.add("ubi*");
7            request.patterns(indexPatterns);
8
9            /** mapping */
10            XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
11                    .startObject()
12                        .startObject("_source")
13                            .field("enabled"false)
14                        .endObject()
15
16                        .startObject("properties")
17                            .startObject("host_name")
18                                .field("type""keyword")
19                            .endObject()
20                            .startObject("created_at")
21                                .field("type""date")
22                                .field("format""yyyy-MM-dd HH:mm:ss")
23                            .endObject()
24
25                        .endObject()
26                    .endObject();
27
28
29            request.mapping("_doc", jsonBuilder);
30
31            Map<StringObject> settings = new HashMap<>();
32
33            settings.put("number_of_shards"1);
34            request.settings(settings);
35
36            System.out.println(client.indices().putTemplate(request, RequestOptions.DEFAULT));
37
38        } catch (Exception e) {
39            // TODO: handle exception
40        } finally {
41            EsClient.close(client);
42        }
43    }

上述索引模板创建好之后,然后在向一个不存在的索引添加文档时,如果能找到合适的模板,则自动创建索引,否则抛出索引不存在,例如:

1public static void index_template() {
2        ElasticsearchTemplate template = new ElasticsearchTemplate();
3        try {
4            Map<String, String> data = new HashMap<>();
5            data.put("host_name""localhost");
6            data.put("created_at""2019-04-07 23:05:04");
7            //ubi_201904该索引一开始不存在,但索引ubi_201904符合ubi_index_template
8            //中定义的匹配表达式ubi*,所以会自动创建索引。
9            template.index("ubi_201904""_doc", data);
10        } finally {
11            template.close();
12        }
13    }

其返回结果:

1IndexResponse[index=ubi_201904,type=_doc,id=lCJZ-GkBrOLJP-QWff3I,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]

那如果能匹配到多个模板呢?

多个索引模板可能匹配一个索引,可以使用order属性为索引模板指定顺序。从顺序较小的开始寻找,order越大,越优先(前提是匹配模板表达式)。

举例如下:

1PUT /_template/template_1
2{
3    "index_patterns" : ["*"],
4    "order" : 0,
5    "settings" : {
6        "number_of_shards" : 1
7    },
8    "mappings" : {
9        "_doc" : {
10            "_source" : { "enabled" : false }
11        }
12    }
13}
14
15PUT /_template/template_2
16{
17    "index_patterns" : ["te*"],
18    "order" : 1,
19    "settings" : {
20        "number_of_shards" : 1
21    },
22    "mappings" : {
23        "_doc" : {
24            "_source" : { "enabled" : true }
25        }
26    }
27}

首先从order=0进行匹配,由于其表达式为*,则默认会全匹配,故首先尝试使用该模板,然后再遍历下一个模板,也就是order=1的模板,如果匹配,则使用第二个模板的配置,如果不匹配,则使用第一个模板的配置,依次类推。

其匹配的具体实现逻辑大概如下:
1、对所有的模板按照order属性进行升序排序。
2、遍历所有的模板,进行表达式匹配,匹配成功,则设置为当前匹配模板,然后判断下一个,直到把所有的模板都处理过。
3、选最后匹配的模板当成最后的模板。

那如果存在多个模板,其order相同,那其顺序能保证吗?

答案是不能保证,因为对所有模板进行排序的过程中,如果order相同,其顺序无法得到保证。

思考:索引模板的使用场景是什么呢?欢迎大家留言讨论。


更多文章请关注微信公众号:


作者新书《RocketMQ技术内幕》已成功上市。

《RocketMQ技术内幕》已出版上市,目前可在主流购物平台(京东、天猫等)购买,本书从源码角度深度分析了RocketMQ NameServer、消息发送、消息存储、消息消费、消息过滤、主从同步HA、事务消息;在实战篇重点介绍了RocketMQ运维管理界面与当前支持的39个运维命令;并在附录部分罗列了RocketMQ几乎所有的配置参数。本书得到了RocketMQ创始人、阿里巴巴Messaging开源技术负责人、Linux OpenMessaging 主席的高度认可并作序推荐。目前是国内第一本成体系剖析RocketMQ的书籍。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存