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

Golang操作MongoDB:按ConfigId分组查最新记录并过滤

MongoDB 查询实现:分组取最新记录并过滤

数据结构(Go)

type History struct {
    ID           primitive.ObjectID `bson:"_id"`
    ConfigId     string             `bson:"configId"`
    IsClosed     bool               `bson:"isClosed"`
    CreatedTime  time.Time          `bson:"createdTime"`
    ValidityTime time.Time          `bson:"validityTime"`
}

需求实现(聚合管道)

直接使用MongoDB聚合管道完成分组取最新、二次过滤的需求,以下是Go语言中的实现代码:

// 获取当前时间
now := time.Now()

// 构建聚合管道
pipeline := []bson.M{
    // 按创建时间倒序排序,确保每组最新记录排在前列
    {"$sort": bson.M{"createdTime": -1}},
    // 按ConfigId分组,取每组第一条(即创建时间最新的记录)
    {"$group": bson.M{
        "_id": "$configId",
        "latestRecord": bson.M{"$first": "$$ROOT"}, // 保留整条记录结构
    }},
    // 将嵌套的最新记录提升为根文档,简化后续过滤
    {"$replaceRoot": bson.M{"newRoot": "$latestRecord"}},
    // 过滤出符合条件的记录
    {"$match": bson.M{
        "isClosed": true,
        "validityTime": bson.M{"$lt": now},
    }},
}

// 执行聚合查询
var results []History
err := collection.Aggregate(context.TODO(), pipeline).All(&results)
if err != nil {
    // 处理查询错误
}

关键阶段说明

  • $sort:全局按createdTime倒序排列,保证同一ConfigId下最新的记录排在最前面
  • $group:按configId分组,用$first获取每组的第一条记录,$$ROOT表示保留整条文档的所有字段
  • $replaceRoot:将分组后嵌套的latestRecord转换为根文档结构,避免后续过滤操作需要嵌套访问字段
  • $match:最终筛选出isClosed为true且validityTime早于当前时间的记录

大数据量优化方案

如果数据集规模极大,全局排序性能受限,可改用先获取每组最大创建时间、再关联原集合的方式:

now := time.Now()

pipeline := []bson.M{
    // 分组获取每组的最大创建时间
    {"$group": bson.M{
        "_id": "$configId",
        "maxCreatedTime": bson.M{"$max": "$createdTime"},
    }},
    // 关联原集合,匹配对应ConfigId和最大创建时间的记录
    {"$lookup": bson.M{
        "from":         "history", // 替换为你的实际集合名称
        "localField":   "_id",
        "foreignField": "configId",
        "pipeline": []bson.M{
            {"$match": bson.M{
                "$expr": bson.M{"$eq": []string{"$createdTime", "$$maxCreatedTime"}},
            }},
        },
        "as": "latestRecords",
    }},
    // 展开关联结果数组
    {"$unwind": "$latestRecords"},
    // 替换为根文档
    {"$replaceRoot": bson.M{"newRoot": "$latestRecords"}},
    // 最终过滤
    {"$match": bson.M{
        "isClosed": true,
        "validityTime": bson.M{"$lt": now},
    }},
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 15:20:33