Go MongoDB 实战:go-mongo-driver 落地大型项目全攻略
MongoDB 是 Go 后端常用 NoSQL。本文从连接池、调优到 transaction 实战,再到企业生产规范,一次打包。
一、driver 安装
go get go.mongodb.org/mongo-driver/mongo连接:
client,err:=mongo.Connect(ctx,options.Client().ApplyURI("mongodb://localhost:27017"))deferclient.Disconnect(ctx)二、CRUD 基本模板
col:=client.Database("shop").Collection("users")// Insertres,err:=col.InsertOne(ctx,bson.M{"name":"tom","age":30})// Findvaruser User err=col.FindOne(ctx,bson.M{"_id":id}).Decode(&user)// Updatefilter:=bson.M{"_id":id}update:=bson.M{"$set":bson.M{"age":31}}_,err=col.UpdateOne(ctx,filter,update)// Delete_,err=col.DeleteOne(ctx,bson.M{"name":"tom"})三、Bson vs 结构体
推荐用 tagged 结构:
typeUserstruct{ID primitive.ObjectID`bson:"_id,omitempty"`Namestring`bson:"name"`Ageint`bson:"age"`}primitive.ObjectID与 MongoDB ObjectId 互转。
四、索引优化
import"go.mongodb.org/mongo-driver/bson"_,err=col.Indexes().CreateOne(ctx,mongo.IndexModel{Keys:bson.D{{"name",1}},// 升序Options:options.Index().SetUnique(true),})生产原则:
- 主键默认存在
- 查询热点字段建索引
- 用
col.Indexes().CreateMany批量建
五、聚合管道
pipeline:=mongo.Pipeline{{{"$match",bson.D{{"status","active"}}}},{{"$group",bson.D{{"_id","$role"},{"count",bson.D{{"$sum",1}}},}}},}cursor,err:=col.Aggregate(ctx,pipeline)聚合管道 = 数据库端复杂逻辑,CPU 节省大。
六、事务(4.x 集群支持)
session,err:=client.StartSession()defersession.EndSession(ctx)_,err=session.WithTransaction(ctx,func(sc mongo.SessionContext)(interface{},error){_,err:=colA.InsertOne(sc,docA)iferr!=nil{returnnil,err}_,err=colB.UpdateOne(sc,bson.M{"_id":id},bson.M{"$inc":bson.M{"counter":1}})returnnil,err})事务要求集群是副本集/分片集群,单机不能用。
七、踩坑清单
- Cursor 必须 Close:防止文件描述符耗尽
- Bson tag 大小写敏感:保持一致
- Update 不存在 → 报错:用 Upsert
- timeout 用 ctx:service 退出时能快速断
- driver 单例:重复 Connect 会浪费 fd
八、调优参数
options.Client().SetMaxPoolSize(100).SetMinPoolSize(10).SetServerSelectionTimeout(500*time.Millisecond).SetSocketTimeout(2*time.Second)配置合适的连接池,是高并发场景关键。
九、生产实战:审计日志模块
funcAudit(ctx context.Context,col*mongo.Collection,opstring,userstring,doc any){_,err:=col.InsertOne(ctx,bson.M{"op":op,"user":user,"doc":doc,"ts":time.Now(),"trace":trace.FromContext(ctx),})iferr!=nil{slog.Error("audit","err",err)}}写入单独的审计库,配合 opentracing,可做到审计 + trace 二合一。
十、总结与展望
go-mongo-driver 是企业级 Go 项目首选 MongoDB 客户端。掌握索引、聚合、事务三件套,能应对从简单 CRUD 到亿级数据的多种场景。
未来:driver 2.x 计划简化 API、提升 stream-friendly、减少反射开销。
十一、参考文献
- MongoDB 官方文档
- go-mongo-driver 仓库
- MongoDB 索引原理解析