使用Mongo Go驱动查询各目的地最新插入文档方法
用MongoDB Go驱动查询每个目的地的最新到访记录
已知集合中存储城市到访记录,自动生成的_id字段随插入时间递增,需求是查询每个destination对应的最新插入文档。
输入示例
[ { "_id": "62e0d290fd1a769bb8ad13ba", "destination": "NY", "airline": "Delta" }, { "_id": "62e0d2defd1a769bb8ad13bb", "destination": "DC", "airline": "Southwest" }, { "_id": "62e0d2defd1a769bb8ad13bc", "destination": "DC", "airline": "American" }, { "_id": "62e0d2defd1a769bb8ad13bd", "destination": "NY", "airline": "JetBlue" } ]
预期输出
[ { "_id": "62e0d2defd1a769bb8ad13bc", "destination": "DC", "airline": "American" }, { "_id": "62e0d2defd1a769bb8ad13bd", "destination": "NY", "airline": "JetBlue" } ]
解决方案
利用MongoDB的聚合管道,结合_id随时间递增的特性,分两步实现:
- 按
destination分组,提取每个分组中最大的_id(即最新插入的记录ID) - 将分组得到的最大
_id与原集合关联,获取完整的文档数据
Go驱动代码示例
首先确保已导入MongoDB Go驱动包:
import ( "context" "fmt" "log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" )
然后编写查询逻辑:
// 定义记录结构体,对应集合中的文档 type VisitRecord struct { ID string `bson:"_id"` Destination string `bson:"destination"` Airline string `bson:"airline"` } func main() { // 连接MongoDB client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017")) if err != nil { log.Fatal(err) } defer func() { if err := client.Disconnect(context.TODO()); err != nil { log.Fatal(err) } }() // 获取集合 collection := client.Database("your_db_name").Collection("your_collection_name") // 构建聚合管道 pipeline := []bson.M{ // 第一步:按destination分组,取每个组的最大_id { "$group": bson.M{ "_id": "$destination", "latestId": bson.M{"$max": "$_id"}, }, }, // 第二步:关联原集合,获取完整文档 { "$lookup": bson.M{ "from": "your_collection_name", // 要关联的集合名 "localField": "latestId", "foreignField": "_id", "as": "latestRecord", }, }, // 第三步:展开数组,提取单个文档 { "$unwind": "$latestRecord", }, // 第四步:投影只保留需要的字段(可选,按需调整) { "$project": bson.M{ "_id": "$latestRecord._id", "destination": "$latestRecord.destination", "airline": "$latestRecord.airline", }, }, } // 执行聚合查询 cursor, err := collection.Aggregate(context.TODO(), pipeline) if err != nil { log.Fatal(err) } defer cursor.Close(context.TODO()) // 解码结果 var results []VisitRecord if err := cursor.All(context.TODO(), &results); err != nil { log.Fatal(err) } // 打印结果 for _, record := range results { fmt.Printf("最新记录:ID=%s, 目的地=%s, 航空公司=%s\n", record.ID, record.Destination, record.Airline) } }
代码说明
$group阶段:按destination分组,用$max获取每个组的最大_id,因为_id随插入时间递增,最大的_id就是最新插入的记录。$lookup阶段:将分组得到的latestId与原集合的_id关联,获取完整的文档数据,结果会放在latestRecord数组中。$unwind阶段:将latestRecord数组展开为单个文档。$project阶段:可选,用于调整输出的字段结构,只保留需要的字段。
内容的提问来源于stack exchange,提问作者manpatha
相关产品推荐
相关产品推荐

