如何在Elasticsearch中优雅设计包含其他类型引用的映射?
优雅复用Elasticsearch映射结构的方案
当然有更优雅的解决办法!Elasticsearch从7.8版本开始支持的**组件模板(Component Templates)**完美匹配你想要的「先定义复用结构,再在其他类型中引用」的需求,就像C++里声明类后复用成员那样,彻底告别重复代码。
方案1:服务端持久化复用(推荐)—— 组件模板
组件模板允许你把重复的字段定义抽成独立的可复用单元,后续在索引模板或单个索引的映射里直接引用,适合长期维护和团队协作场景。
第一步:创建复用的A类型组件模板
先把类型A的所有属性定义成一个组件模板:
PUT _component_template/A_component { "template": { "mappings": { "properties": { "A1": {"type": "keyword"}, "A2": {"type": "keyword"}, "A3": {"type": "keyword"} // 修正了你示例中重复的A2字段,改为A3 } } } }
第二步:在索引模板中引用组件模板
创建索引模板时,通过composed_of字段引入A组件,然后在A类型和B的Field_A字段中直接复用其属性定义:
PUT _index_template/my_index_template { "index_patterns": ["my_index*"], // 匹配所有以my_index开头的索引 "composed_of": ["A_component"], "template": { "mappings": { "properties": { // 类型A直接复用组件模板的属性 "A": { "properties": "{{A_component.template.mappings.properties}}" }, // 类型B的定义,其中Field_A复用A的属性 "B": { "properties": { "B1": {"type": "keyword"}, "B2": {"type": "keyword"}, "B3": {"type": "keyword"}, "Field_A": { "properties": "{{A_component.template.mappings.properties}}" } } } } } } }
后续只要创建符合my_index*规则的索引,就会自动应用这个包含复用结构的映射。如果需要修改A类型的属性,只需要更新A_component组件模板,新创建的索引就会自动生效。
方案2:客户端临时复用—— 变量拼接
如果只是临时创建单个索引,不想维护组件模板,也可以在客户端通过变量拼接的方式避免重复代码(以curl为例):
# 先定义A类型的属性为变量 A_PROPERTIES='{"A1":{"type":"keyword"},"A2":{"type":"keyword"},"A3":{"type":"keyword"}}' # 创建索引时引用该变量 curl -XPUT "http://localhost:9200/my_single_index" -H "Content-Type: application/json" -d '{ "mappings": { "properties": { "A": { "properties": '"$A_PROPERTIES"' }, "B": { "properties": { "B1": {"type": "keyword"}, "B2": {"type": "keyword"}, "B3": {"type": "keyword"}, "Field_A": { "properties": '"$A_PROPERTIES"' } } } } } }'
这种方式适合快速测试或临时场景,但不适合长期维护,因为复用逻辑只存在于客户端脚本中。
注意:你提供的官方示例里重复定义了三次
A2字段,这是无效的,JSON中重复的键会被覆盖,我在示例中改为了A1/A2/A3三个不同字段。
内容的提问来源于stack exchange,提问作者maidamai
相关产品推荐
相关产品推荐

