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

Elasticsearch按字段分组获取每组得分最高的单条记录

按类别获取每组匹配得分最高的单条记录

问题说明

我是Elasticsearch新手,想要实现:在comment字段搜索指定内容后,按category分组,每组只返回匹配得分最高的单条记录。

索引详情

创建索引的请求如下:

PUT commentdetail
{
  "mappings": {
    "properties": {
      "category": {
        "type": "text"
      },
      "comment": {
        "type": "text"
      }
    }
  }
}

示例数据

categoryComment
fruitI like apple
fruitI like apple and banana
fruitI like banana and apple
fruitI like banana but not apple
fruitI like apple but not banana
fruitI like banana
vegetableI like potato
vegetableI like potato and tomato
vegetableI like tomato and potato
vegetableI like tomato but not potato
vegetableI like potato but not tomato
vegetableI like tomato

期望结果

当在comment字段搜索"I like"时,希望得到如下结果:

categoryComment
fruitI like apple
vegetableI like potato

解决方案

可以通过terms聚合结合top_hits子聚合实现需求,查询语句如下:

GET commentdetail/_search
{
  "size": 0, // 不返回原始搜索结果,只返回聚合结果
  "query": {
    "match_phrase": {
      "comment": "I like"
    }
  },
  "aggs": {
    "group_by_category": {
      "terms": {
        "field": "category.keyword", // 用keyword字段分组,避免text分词导致的分组错误
        "size": 10 // 根据实际类别数量调整取值
      },
      "aggs": {
        "top_comment": {
          "top_hits": {
            "size": 1, // 每组仅取1条得分最高的记录
            "_source": ["category", "comment"], // 指定返回字段
            "sort": [
              {
                "_score": { // 按匹配得分降序排序
                  "order": "desc"
                }
              }
            ]
          }
        }
      }
    }
  }
}

结果解析

聚合结果会在aggregations.group_by_category.buckets节点下,每个bucket对应一个分类,其中top_comment.hits.hits[0]就是该分类下得分最高的记录。如果需要更简洁的输出格式,可以对聚合结果做后续整理。

注意:如果创建索引时未给category字段配置keyword子字段,需要先更新映射,否则terms聚合会因text字段分词无法正确分组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:31:16