Elasticsearch嵌套属性字段mapping创建及聚合统计实现咨询
方案说明
针对你需要统计商品属性出现频次的业务需求,推荐按以下方式设计Elasticsearch Mapping,分两种实现路径:
方案一:预处理字段(推荐,性能最优)
写入ES前对原始数据做简单清洗,将当前商品所有来源(src1/src2等)下出现过的属性名去重后,存入独立的attribute_names字段,专门用于聚合统计。
Mapping示例
{ "mappings": { "properties": { // 商品基础字段可自行扩展,示例仅列相关字段 "attribute_names": { "type": "keyword", "doc_values": true }, // 保留原始多来源属性结构,满足其他查询需求 "attributes_list": { "properties": { "src1": { "type": "nested", "properties": { "aname": {"type": "keyword"}, "avalue": {"type": "keyword"} } }, "src2": { "type": "nested", "properties": { "aname": {"type": "keyword"}, "avalue": {"type": "keyword"} } } } } } } }
聚合查询示例
直接对attribute_names做terms聚合即可拿到属性的出现频次:
{ "size": 0, "aggs": { "most_used_attributes": { "terms": { "field": "attribute_names", "size": 200 // 调整该值获取对应数量的高频属性 } } } }
返回结果中每个桶的key为属性名,doc_count即为包含该属性的商品数量,完全匹配你需要的Color(doc_count=2)的统计效果。
方案二:无预处理,直接基于原始结构聚合(适合数据量较小的场景)
如果不想修改数据写入逻辑,也可以直接基于原始结构用嵌套聚合实现,性能略低于方案一:
Mapping示例
{ "mappings": { "properties": { "attributes_list": { "properties": { "src1": { "type": "nested", "properties": { "aname": {"type": "keyword"}, "avalue": {"type": "keyword"} } }, "src2": { "type": "nested", "properties": { "aname": {"type": "keyword"}, "avalue": {"type": "keyword"} } } } } } } }
聚合查询示例
{ "size": 0, "aggs": { "src1_attrs": { "nested": { "path": "attributes_list.src1" }, "aggs": { "src1_names": { "terms": { "field": "attributes_list.src1.aname", "size": 200 } } } }, "src2_attrs": { "nested": { "path": "attributes_list.src2" }, "aggs": { "src2_names": { "terms": { "field": "attributes_list.src2.aname", "size": 200 } } } } } }
查询后对两个来源的聚合结果自行合并统计即可。
注意事项
- 所有属性名、属性值字段都要设为
keyword类型,不能用text类型,否则terms聚合会按分词结果统计,不符合需求。 - 每个来源下的属性数组必须设为
nested类型,避免ES扁平化数组导致aname和avalue的对应关系丢失,方便后续实现「属性名+属性值」的组合筛选需求。
内容的提问来源于stack exchange,提问作者Imran Khan
相关产品推荐
相关产品推荐

