Elasticsearch动态模板未生效,需将对象内字段默认设为文本类型
我懂你想要实现的效果:让myObj这个对象字段下的所有子字段,不管传入的值是什么类型,默认都映射成text类型。但当前的动态模板没按预期工作,咱们来一步步排查和修复这个问题。
先给你一个能正常工作的完整映射示例
首先,补全并修正你的索引创建语句,确保核心逻辑正确:
PUT myindex { "mappings": { "doc": { "dynamic_templates": [ { "myObj_default_string": { "path_match": "myObj.*", "match_mapping_type": "*", "mapping": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } ], "properties": { "dummy_field_name": { "type": "text" }, "timestamp": { "type": "date" }, "myObj": { "type": "object" // 关键:显式声明这个字段是object类型 } } } } }
排查你之前模板失效的可能原因
没显式声明
myObj是object类型
如果不在properties里明确把myObj定义成object,Elasticsearch第一次写入数据时可能会自动推断它的类型(比如如果第一个子字段是数字,可能误判),导致动态模板的path_match无法匹配。一定要显式声明这个字段的类型为object。动态模板的优先级问题
如果你有多个动态模板,Elasticsearch会匹配第一个符合条件的模板。确保你的myObj_default_string模板放在所有其他模板的前面,避免被其他模板抢先匹配。已有字段的映射已经被自动创建
如果你在设置动态模板之前就已经往myObj下写入过数据,Elasticsearch已经自动生成了这些子字段的映射,动态模板不会修改已有的映射。这种情况下,你需要删除索引重新创建,或者通过重新索引的方式更新字段映射(注意:部分字段类型无法直接修改,比如从long改成text,必须重新索引)。Elasticsearch版本差异(7.x+需注意)
7.x及以后的版本已经废弃了自定义类型名(比如你用的doc),默认使用_doc,或者可以直接去掉类型层级。如果你的ES版本是7.x+,可以用下面的写法:
PUT myindex { "mappings": { "dynamic_templates": [ { "myObj_default_string": { "path_match": "myObj.*", "match_mapping_type": "*", "mapping": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } ], "properties": { "dummy_field_name": { "type": "text" }, "timestamp": { "type": "date" }, "myObj": { "type": "object" } } } }
验证模板是否生效
创建索引后,写入一条测试数据:
POST myindex/_doc { "myObj": { "test_num": 123, "test_bool": true, "test_text": "hello world" } }
然后查看索引映射:
GET myindex/_mapping
你会看到myObj下的所有子字段类型都被设置成了text,并且带有keyword子字段(方便精确查询)。
内容的提问来源于stack exchange,提问作者silent phantom

