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

Golang中MongoDB指定用户最近5条评分的中位数计算问题

解决Golang中MongoDB计算用户最近5条反馈rating中位数的问题

一、修正现有聚合阶段的错误

你现有代码里的两处问题确实存在,修正后的基础聚合阶段代码如下:

// 匹配指定user_id的记录,替换原错误的_id匹配条件
matchStage := bson.D{{"$match", bson.D{{"user_id", userID}}}}
// 按received_at降序排序,获取最近的记录,替换原错误的created_at字段
sortStage := bson.D{{"$sort", bson.D{{"received_at", -1}}}}
// 限制取最近5条记录
limitStage := bson.D{{"$limit", 5}}

二、补充中位数计算的完整聚合逻辑

MongoDB聚合框架可以通过以下步骤实现中位数计算,完整代码如下:

// 1. 匹配目标用户的反馈记录
matchStage := bson.D{{"$match", bson.D{{"user_id", userID}}}}
// 2. 按接收时间降序排序,取最近5条
sortStage := bson.D{{"$sort", bson.D{{"received_at", -1}}}}
limitStage := bson.D{{"$limit", 5}}
// 3. 收集rating到数组,并统计记录数量
groupStage := bson.D{
    {"$group", bson.D{
        {"_id", "$user_id"},
        {"ratings", bson.D{{"$push", "$rating"}}},
        {"count", bson.D{{"$sum", 1}}},
    }},
}
// 4. 根据记录数奇偶性计算中位数
projectStage := bson.D{
    {"$project", bson.D{
        {"user_id", "$_id"},
        {"_id", 0},
        {"median", bson.D{
            {"$cond", bson.A{
                // 判断记录数是否为偶数
                {"$even", "$count"},
                // 偶数情况:取中间两个数的平均值
                {"$avg", bson.A{
                    {"$arrayElemAt", bson.A{"$ratings", {"$subtract", bson.A{{"$divide", bson.A{"$count", 2}}}, 1}}},
                    {"$arrayElemAt", bson.A{"$ratings", {"$divide", bson.A{"$count", 2}}}},
                }},
                // 奇数情况:取数组中间位置的元素
                {"$arrayElemAt", bson.A{"$ratings", {"$floor", bson.D{{"$divide", bson.A{"$count", 2}}}}}},
            }},
        }},
    }},
}

// 执行聚合查询
cursor, err := r.c.Aggregate(ctx, mongo.Pipeline{matchStage, sortStage, limitStage, groupStage, projectStage})
if err != nil {
    return 0.0, err
}
defer cursor.Close(ctx)

// 解析聚合结果
var medianResult struct {
    UserID string  `bson:"user_id"`
    Median float64 `bson:"median"`
}
if cursor.Next(ctx) {
    if err := cursor.Decode(&medianResult); err != nil {
        return 0.0, err
    }
}

return medianResult.Median, nil

三、关键说明

  • 排序使用-1(降序)可直接获取最近的5条记录,比升序后取最后5条更高效
  • 中位数计算兼容记录数不足5条的场景,逻辑会自动适配实际记录数的奇偶性
  • 最终结果会根据记录数返回整数(奇数条)或浮点数(偶数条的平均值)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:52:47