第四阶段 34 · 索引模板与 data stream(自动套 mapping / 时序数据)
2026/8/3 16:53:37 网站建设 项目流程

34 · 索引模板与 data stream(自动套 mapping / 时序数据)

阶段:第四阶段 / 写入与索引管理
ES:index template / component template / data stream | PostgreSQL:CREATE TABLE ... LIKE模板 + 分区表


1. 概念

前面第 33 篇是「手动建一个索引」。但真实场景里索引常常是动态创建
(按天/按月滚动,如logs-2026.08.01),你不可能每次手写 mapping。

  • index template(索引模板):预先定义「索引名匹配某模式时,自动套用哪套 settings/mappings」。
    新索引一创建就自动带上正确结构。
  • component template(组件模板):可复用的 mapping/settings 片段,多个索引模板拼装它,避免重复。
  • data stream(数据流):面向只追加的时序数据(日志、指标、事件)的高级抽象——
    你只对一个名字写入,底层自动滚动出一串隐藏索引,配合 ILM 自动管理生命周期。

2. PostgreSQL 对照

ESPostgreSQL
component template可复用的列定义 /LIKE table INCLUDING ALL
index template「新表自动套用某结构」的约定
data stream分区表(按时间自动路由到子分区,只追加)
rollover分区滚动(新月份自动进新分区)

3. ES DSL

3.1 组件模板(可复用片段)

PUT _component_template/base_settings { "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 1 } } } PUT _component_template/sales_mappings { "template": { "mappings": { "properties": { "record_id": { "type": "keyword" }, "amount": { "type": "double" }, "@timestamp": { "type": "date" } } } } }

3.2 索引模板(匹配索引名,拼装组件)

PUT _index_template/sales_template { "index_patterns": ["sales-*"], // 索引名匹配 sales-* 就套用 "composed_of": ["base_settings", "sales_mappings"], "priority": 200, // 多模板命中时取优先级高的 "template": { "aliases": { "sales": {} } // 顺便挂别名 } }

之后任何sales-2026.08之类的新索引,一写入就自动带上上面的结构和别名。

3.3 data stream(时序,只追加)

# 模板里声明这是 data stream 模板 PUT _index_template/logs_template { "index_patterns": ["logs-*"], "data_stream": {}, "composed_of": ["base_settings"], "priority": 200 } # 直接往 data stream 写(必须带 @timestamp) POST logs-app/_doc { "@timestamp": "2026-08-01T10:00:00Z", "level": "INFO", "msg": "started" } # 手动滚动(通常交给 ILM 自动做) POST logs-app/_rollover

data stream 只支持create(追加),不能像普通索引那样对历史文档随意update/delete
(要改走_update_by_query,第 32 篇)。


4. Spring Boot 实现

@ComponentpublicclassDoc34Template{@AutowiredprivateElasticsearchClientelasticsearchClient;/** 建/更新索引模板:mapping 外置成 JSON,用 withJson 直灌(对照第 09 篇) */publicvoidputIndexTemplate(Stringname,StringtemplateJson)throwsIOException{PutIndexTemplateRequestreq=PutIndexTemplateRequest.of(b->b.name(name).withJson(newStringReader(templateJson)));// 整段模板 DSL 直灌booleanok=elasticsearchClient.indices().putIndexTemplate(req).acknowledged();if(!ok){thrownewIllegalStateException("put index template 失败: "+name);}}/** 对 data stream 手动触发一次 rollover(一般由 ILM 自动完成) */publicvoidrollover(StringdataStream)throwsIOException{elasticsearchClient.indices().rollover(r->r.alias(dataStream));}}

import:co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest
模板 JSON 外置到resources/es-template/*.json,改结构不必改 Java(同第 09 篇思路)。


5. 坑与最佳实践

  1. 模板只对“之后创建的索引”生效:改了模板不会回改已存在的索引。
  2. priority决多模板冲突:索引名同时命中多个模板时,取priority最高的那个(不叠加)。
  3. data stream 必须有@timestamp:这是它排序/滚动的依据。
  4. data stream 配 ILM 才完整:滚动、降副本、迁冷、删除交给 ILM 自动做(见运维篇/官方 ILM)。
  5. 优先用 component template 拆公共片段:多索引共享 settings/mapping,避免复制粘贴漂移。
  6. 别用旧的_template(legacy):8.x 用_index_template+_component_template

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询