Elasticsearch实现SELECT DISTINCT(color),car_price FROM cars的查询方案
实现Elasticsearch中类似
SELECT DISTINCT(color), car_price FROM cars的查询 嘿,我懂你的需求啦——你想按color去重,同时拿到每个唯一颜色对应的car_price字段。在Elasticsearch里没法直接写SQL那样的DISTINCT语句,但我们可以用聚合+子聚合的组合来实现这个效果,下面给你两种实用的方案:
方案1:Terms聚合 + Top Hits子聚合
如果同一个color可能对应多个car_price(但你只需要获取其中一条记录的价格),或者你想控制返回价格对应的文档(比如最新录入的),这个方案最合适。它会先按color分组,再在每个分组里提取指定字段内容:
GET /cars/_search { "size": 0, // 不需要返回原始文档,只关注聚合结果 "aggs": { "distinct_colors": { "terms": { "field": "color.keyword", // 注意:如果color是text类型,必须用keyword子字段做精确分组 "size": 10000 // 根据你的数据量调整,确保能返回所有唯一颜色 }, "aggs": { "car_price_info": { "top_hits": { "size": 1, // 每个颜色只取1条记录的价格 "_source": ["car_price"] // 只返回需要的字段,减少数据传输量 } } } } } }
结果解析
聚合结果里的distinct_colors.buckets会包含每个唯一颜色的分组,每个分组下的car_price_info.hits.hits[0]._source.car_price就是对应的价格。
方案2:Terms聚合 + Min/Max子聚合
如果每个color对应的car_price是唯一的(比如同色车型价格固定),可以用这种更简洁的方式:因为唯一值的min和max结果一致,直接聚合出这个值就行:
GET /cars/_search { "size": 0, "aggs": { "distinct_colors": { "terms": { "field": "color.keyword", "size": 10000 }, "aggs": { "car_price": { "min": { // 换成"max"结果也一样,因为值唯一 "field": "car_price" } } } } } }
结果解析
每个颜色分组下的car_price.value就是对应的唯一价格,比Top Hits的结果更直接清晰。
至于你之前看到的聚合桶只有key,是因为单纯的terms聚合默认只返回分组的key(也就是颜色值)和doc_count(该颜色的文档数量),要获取关联字段必须在terms聚合内部添加子聚合,才能把分组和对应的字段值绑定起来。
内容的提问来源于stack exchange,提问作者Pranesh
相关产品推荐
相关产品推荐

