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

如何使用Go操作MongoDB实现分组查询取组内height最高记录

Go操作MongoDB实现按用户分组取身高最大值记录

基础信息

测试数据集

userId   height 

curry      1
curry      2
kd         3
kd         4
james      2

查询入参

userIds=[curry,kd,james]

期望返回结果

curry      2
kd         4
james      2

需求规则

按userId字段分组,返回每个分组中height字段值最高的对应单条记录,基于Go语言+MongoDB实现。

实现方案

MongoDB端通过聚合管道完成分组计算,核心逻辑分为4个阶段:

  • $match:提前过滤出入参列表内的用户记录,减少后续聚合计算的数据量
  • $sort:对过滤后的数据按userId升序、height降序排序,保证同一用户下身高最高的记录排在分组最前
  • $group:按userId做分组,通过$first操作符取每个分组排序后的第一条完整记录
  • $replaceRoot:将分组拿到的记录提升为根节点,保证返回结构和普通查询的文档结构一致

代码实现

  1. 依赖准备:安装官方MongoDB Go驱动
    go get go.mongodb.org/mongo-driver/mongo
    
  2. 定义文档对应的结构体
    type UserHeight struct {
        UserId string `bson:"userId"`
        Height int    `bson:"height"`
    }
    
  3. 核心查询逻辑
    // 此处提前完成MongoDB连接初始化,col为对应集合的*mongo.Collection实例
    ctx := context.Background()
    // 入参用户ID列表
    queryUserIds := []string{"curry", "kd", "james"}
    
    // 构造聚合管道
    pipeline := mongo.Pipeline{
        {
            {Key: "$match", Value: bson.D{
                {Key: "userId", Value: bson.D{{Key: "$in", Value: queryUserIds}}},
            }},
        },
        {
            {Key: "$sort", Value: bson.D{
                {Key: "userId", Value: 1},
                {Key: "height", Value: -1},
            }},
        },
        {
            {Key: "$group", Value: bson.D{
                {Key: "_id", Value: "$userId"},
                {Key: "record", Value: bson.D{{Key: "$first", Value: "$$ROOT"}}},
            }},
        },
        {
            {Key: "$replaceRoot", Value: bson.D{{Key: "newRoot", Value: "$record"}}},
        },
    }
    
    // 执行聚合查询
    cursor, err := col.Aggregate(ctx, pipeline)
    if err != nil {
        log.Fatalf("执行聚合查询失败: %v", err)
    }
    defer cursor.Close(ctx)
    
    // 解析结果集
    var resultList []UserHeight
    if err = cursor.All(ctx, &resultList); err != nil {
        log.Fatalf("解析查询结果失败: %v", err)
    }
    
    // 输出验证
    for _, item := range resultList {
        fmt.Printf("%-10s %d\n", item.UserId, item.Height)
    }
    

注意事项

  • 生产环境建议给userId字段创建单键索引,能大幅提升匹配、排序阶段的执行效率
  • 如果同一用户下存在多条height同为最大值的记录,上述逻辑会返回排序后排在最前的条目,如果需要固定返回规则,可以在$sort阶段追加排序字段(比如_id降序)保证结果一致性
  • 聚合阶段用$$ROOT获取完整文档的写法兼容性更好,后续集合新增字段时不需要调整聚合逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:42:25