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

Elasticsearch如何按用户分组取评分最高的TopN首歌曲(仅统计最新评分)

解决方案

原查询问题分析

你写的查询存在两个核心问题导致没有得到预期结果:

  1. top_hits 嵌套在timestamp子聚合中,仅能返回每首歌曲的最新1条评分,但没有对同一用户下的所有歌曲按照最新评分做全局排序
  2. track_id的terms分组默认按文档出现次数排序,没有按评分字段排序,自然拿不到评分最高的前N首

调整后兼容全版本的查询(示例取Top10,可自行修改size参数)

{
  "size": 0,
  "aggs": {
    "group_by_user": {
      "terms": {
        "field": "user_id.keyword",
        "size": 10 // 按需调整需要返回的用户总数
      },
      "aggs": {
        "group_by_track": {
          "terms": {
            "field": "track_id.keyword",
            "size": 1000 // 建议设置为大于单个用户最多评分歌曲数,避免遗漏数据
          },
          "aggs": {
            // 取该用户对该歌曲的最新1条评分记录
            "latest_rating": {
              "top_hits": {
                "sort": [{"timestamp": "desc"}],
                "size": 1,
                "_source": ["title", "artist", "score", "timestamp"]
              }
            },
            // 提取最新评分的分数用于后续排序
            "latest_score": {
              "max": {
                "field": "score"
              }
            }
          }
        },
        // 对所有歌曲按最新评分倒序,取TopN
        "top_n_tracks": {
          "bucket_sort": {
            "buckets_path": "group_by_track>latest_score",
            "sort": [{"group_by_track>latest_score": "desc"}],
            "size": 10 // 这里就是你要的TopN的N值
          }
        }
      }
    }
  }
}

ES7.11+版本优化写法(性能更高)

高版本可以用top_metrics聚合替代top_hits,不需要额外提取排序字段,执行效率更高:

{
  "size": 0,
  "aggs": {
    "group_by_user": {
      "terms": {
        "field": "user_id.keyword",
        "size": 10
      },
      "aggs": {
        "group_by_track": {
          "terms": {
            "field": "track_id.keyword",
            "size": 1000
          },
          "aggs": {
            "latest_record": {
              "top_metrics": {
                "metrics": [
                  {"field": "score"},
                  {"field": "title"},
                  {"field": "artist"}
                ],
                "sort": {"timestamp": "desc"}
              }
            }
          }
        },
        "top_10_tracks": {
          "bucket_sort": {
            "buckets_path": "group_by_track>latest_record.score",
            "sort": [{"group_by_track>latest_record.score": "desc"}],
            "size": 10
          }
        }
      }
    }
  }
}

核心逻辑说明

  • 先按用户ID分组,再按歌曲ID分组,保证每个用户的每首歌曲独立成桶
  • 每个歌曲桶内按时间戳倒序取第一条记录,自动过滤掉同一用户同一首歌的历史评分,仅保留最新一条
  • 用bucket_sort聚合对同一用户下的所有歌曲桶按最新评分倒序排列,取前N条即可得到目标结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:57:02