You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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"}}]
}

当前问题

执行上述查询后,结果顺序为:

  1. Playstation 5
  2. Steam Deck
  3. Nintendo Switch

但按各产品最低价排序的正确顺序应为:

  1. Playstation 5(最低价500)
  2. Nintendo Switch(最低价200)
  3. 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"}}]
                    }
                }
            }
        }
    }
}

说明

  1. terms聚合按name字段分组,确保每个产品仅出现一次
  2. 内层top_hits聚合设置size=1并按price升序排序,获取每个分组的最低价文档
  3. terms聚合的order参数指定按cheapest_price(即top_hits返回的最低价)降序排列
  4. 设置size=0是为了不返回原始文档,仅输出聚合结果

执行该查询后,将得到按最低价降序排列的产品列表,每个产品仅展示其最低价记录。


内容的提问来源于stack exchange,提问作者mnj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 08:35:02