Elasticsearch中定义动态映射索引字段的最优方法及查询实现
索引映射定义
针对动态键场景,为避免字段爆炸同时提升查询效率,推荐两种映射方案:
方案1:无需改动原始写入结构(适配你给出的示例数据格式)
通过动态模板将entity下所有动态字段的值统一复制到专属聚合字段,查询时直接命中聚合字段即可,效率最高。
映射代码如下:
PUT /your_index_name { "mappings": { "dynamic_templates": [ { "entity_dynamic_fields": { "path_match": "entity.*", "mapping": { "type": "keyword", "copy_to": "entity.all_values" } } }, { "similarities_dynamic_fields": { "path_match": "similarities.*", "mapping": { "type": "keyword" } } } ], "properties": { "similarities": { "type": "nested" }, "entity": { "properties": { "all_values": { "type": "keyword" } } } } } }
方案说明:
entity.*的动态模板会自动匹配entity下所有动态生成的键,统一映射为keyword类型适合精确匹配,同时所有值会被拷贝到entity.all_values字段,无需遍历所有动态键即可完成全字段值查询。- similarities声明为nested类型,避免数组对象扁平化后键值关联关系丢失,所有动态键也统一映射为keyword类型。
方案2:可调整写入结构(彻底避免字段爆炸,更推荐生产环境使用)
将动态键值对改造为固定key、value字段的数组结构,彻底解决动态键过多导致的映射爆炸问题。
改造后的写入数据示例:
{ "similarities": [ { "props": [ {"key": "key1", "value": "value1"}, {"key": "key2", "value": "value2"} ] }, { "props": [ {"key": "key3", "value": "value1"}, {"key": "key4", "value": "value2"} ] } ], "entity": [ {"key": "version", "value": "SO"}, {"key": "Non-Commerical", "value": "GGP"} ] }
对应的映射代码:
PUT /your_index_name { "mappings": { "properties": { "similarities": { "type": "nested", "properties": { "props": { "type": "nested", "properties": { "key": {"type": "keyword"}, "value": {"type": "keyword"} } } } }, "entity": { "type": "nested", "properties": { "key": {"type": "keyword"}, "value": {"type": "keyword"} } } } } }
查询语句
对应方案1的查询
直接查询聚合字段entity.all_values即可:
POST /your_index_name/_search { "query": { "term": { "entity.all_values": "GGP" } } }
对应方案2的查询
通过nested查询命中entity下的value字段:
POST /your_index_name/_search { "query": { "nested": { "path": "entity", "query": { "term": { "entity.value": "GGP" } } } } }
内容的提问来源于stack exchange,提问作者Kaushal panchal
相关产品推荐
相关产品推荐

