如何基于Collapsed inner_hits对Elasticsearch结果按最低价排序?
问题:按折叠后inner_hits中的最低价排序Elasticsearch结果
原始数据
Elasticsearch中的文档如下(每个对象为独立文档):
[ {"name": "Steam Deck", "price": 100}, {"name": "Steam Deck", "price": 800}, {"name": "Nintendo Switch", "price": 200}, {"name": "Nintendo Switch", "price": 700}, {"name": "Playstation 5", "price": 500}, {"name": "Playstation 5", "price": 1000} ]
需求
获取所有产品的列表,展示每个产品的最低价,并按该最低价降序排列。
当前查询语句
尝试使用collapse字段折叠相同name的文档,并通过inner_hits获取最低价:
{ "from": 0, "size": 30, "collapse": { "field": "name", "inner_hits": { "name": "cheapest", "size": 1, "sort": [{"price": {"order": "asc"}}] } }, "sort": [{"price": {"order": "desc"}}] }
当前问题
执行上述查询后,结果顺序为:
- Playstation 5
- Steam Deck
- Nintendo Switch
但按各产品最低价排序的正确顺序应为:
- Playstation 5(最低价500)
- Nintendo Switch(最低价200)
- Steam Deck(最低价100)
疑问:能否基于折叠后的inner_hits中的价格字段对结果进行排序?
解决方案:使用聚合替代collapse
collapse的排序逻辑基于主文档字段,无法直接引用inner_hits中的字段排序。建议使用terms聚合分组+top_hits聚合获取最低价,并基于聚合结果排序:
{ "size": 0, "aggs": { "products": { "terms": { "field": "name", "size": 30, "order": { "cheapest_price": "desc" } }, "aggs": { "cheapest_price": { "top_hits": { "size": 1, "sort": [{"price": {"order": "asc"}}] } } } } } }
说明
terms聚合按name字段分组,确保每个产品仅出现一次- 内层
top_hits聚合设置size=1并按price升序排序,获取每个分组的最低价文档 terms聚合的order参数指定按cheapest_price(即top_hits返回的最低价)降序排列- 设置
size=0是为了不返回原始文档,仅输出聚合结果
执行该查询后,将得到按最低价降序排列的产品列表,每个产品仅展示其最低价记录。
内容的提问来源于stack exchange,提问作者mnj
相关产品推荐
相关产品推荐

