17.1Go语言操作MongoDB

server/2025/3/23 8:11:58/

驱动安装

go get go.mongodb.org/mongo-driver/mongo

基础连接示例


package mainimport ("context""fmt""log""time""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options"
)func main() {// 设置客户端选项clientOptions := options.Client().ApplyURI("mongodb://localhost:27017").SetConnectTimeout(10 * time.Second)// 连接MongoDBclient, err := mongo.Connect(context.Background(), clientOptions)if err != nil {log.Fatal(err)}defer func() {if err = client.Disconnect(context.Background()); err != nil {log.Fatal(err)}}()fmt.Println("成功连接到MongoDB!")
}

标题数据库操作

  1. 创建数据库和集合
db := client.Database("mydb")
usersColl := db.Collection("users")
  1. 文档定义(结构体)
type User struct {ID       primitive.ObjectID `bson:"_id,omitempty" json:"id"`Username string             `bson:"username" json:"username"`Email    string             `bson:"email" json:"email"`CreatedAt time.Time        `bson:"createdAt" json:"created_at"`
}

CRUD操作

  1. 插入文档
insertResult, err := usersColl.InsertOne(context.Background(),User{Username: "john_doe",Email:    "john@example.com",CreatedAt: time.Now(),},
)if err != nil {log.Fatal(err)
}fmt.Printf("插入ID: %v\n", insertResult.InsertedID)
  1. 查询文档
filter := bson.D{{"username", "john_doe"}}
var results []Usercursor, err := usersColl.Find(context.Background(), filter)
if err != nil {log.Fatal(err)
}defer cursor.Close(context.Background())if err = cursor.All(context.Background(), &results); err != nil {log.Fatal(err)
}fmt.Printf("找到%d个用户:\n", len(results))
for _, user := range results {fmt.Printf("- %s (%s)\n", user.Username, user.Email)
}
  1. 更新文档

updateFilter := bson.D{{"username", "john_doe"}}
update := bson.D{{"$set", bson.D{{"email", "john_new@example.com"}}}}result, err := usersColl.UpdateOne(context.Background(),updateFilter,update,
)if err != nil {log.Fatal(err)
}fmt.Printf("匹配到%d个文档,更新%d个\n", result.MatchedCount, result.UpdatedCount)
  1. 删除文档

deleteResult, err := usersColl.DeleteOne(context.Background(),bson.D{{"username", "john_doe"}},
)if err != nil {log.Fatal(err)
}fmt.Printf("删除%d个文档\n", deleteResult.DeletedCount)

聚合操作

pipeline := mongo.Pipeline{{{"$match", bson.D{{"status", "active"}}}},{{"$group", bson.D{{"_id", bson.D{{"department", "$department"}}},{"total", bson.D{{"$sum", 1}}},}}},
}var results []bson.M
cursor, err := usersColl.Aggregate(context.Background(), pipeline)
if err != nil {log.Fatal(err)
}defer cursor.Close(context.Background())if err = cursor.All(context.Background(), &results); err != nil {log.Fatal(err)
}fmt.Println("部门用户统计:")
for _, doc := range results {fmt.Printf("%s: %d人\n", doc["_id"].(string), doc["total"].(int32))
}

事务处理

session, err := client.StartSession()
if err != nil {log.Fatal(err)
}
defer session.EndSession(context.Background())txOptions := options.Transaction().SetReadConcern(readconcern.Majority()).SetWriteConcern(writeconcern.Majority())err = session.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) error {// 在事务中执行多个操作_, err := usersColl.InsertOne(sessCtx, User{Username: "alice"})if err != nil {return err}_, err = ordersColl.InsertOne(sessCtx, Order{UserID: "alice", Total: 100})if err != nil {return err}return nil
}, txOptions)if err != nil {log.Fatal("事务失败:", err)
} else {fmt.Println("事务成功")
}

高级功能

  1. 索引管理

indexModel := mongo.IndexModel{Keys: bson.D{{"username", 1}},
}_, err = usersColl.Indexes().CreateOne(context.Background(),indexModel,
)if err != nil {log.Fatal(err)
}
fmt.Println("索引创建成功")
  1. 分页查询

pageSize := 10
pageNumber := 2filter := bson.D{}
sort := bson.D{{"createdAt", -1}}optionsFind := options.Find().SetLimit(int64(pageSize)).SetSkip(int64((pageNumber-1)*pageSize)).SetSort(sort)cursor, err := usersColl.Find(context.Background(), filter, optionsFind)
// 处理游标...

错误处理

func safeMongoOp(ctx context.Context, op func() (interface{}, error)) (interface{}, error) {ctx, cancel := context.WithTimeout(ctx, 5*time.Second)defer cancel()result, err := op()if err != nil {return nil, fmt.Errorf("mongo operation failed: %w", err)}return result, nil
}

连接池配置

clientOptions := options.Client().ApplyURI("mongodb://localhost:27017").SetMaxPoolSize(100).SetMinPoolSize(10).SetConnectTimeout(10 * time.Second).SetSocketTimeout(30 * time.Second)

资源清理


// 使用defer确保资源释放
cursor, err := collection.Find(ctx, filter)
if err != nil {// 处理错误
}defer cursor.Close(ctx)

性能优化建议

  • 使用批量操作(InsertMany/UpdateMany)
  • 合理使用索引
  • 限制查询结果集大小
  • 使用投影(Projection)减少数据传输
  • 适当使用缓存机制

测试

setupTestDB(t)// 测试插入user := User{Username: "test_user"}insertResult, _ := collection.InsertOne(context.Background(), user)// 测试查询filter := bson.D{{"username", "test_user"}}var foundUser Usererr := collection.FindOne(context.Background(), filter).Decode(&foundUser)// 清理测试数据_, _ = collection.DeleteOne(context.Background(), bson.D{{"_id", insertResult.InsertedID}})

简单完整例子

package main import ("context""fmt""log""time""go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" 
)
// 定义数据结构体 
type User struct {Name  string `bson:"name"`Email string `bson:"email"`Age   int    `bson:"age"`
}func main() {// 1. 连接 MongoDB client, err := mongo.Connect(context.TODO(),options.Client().ApplyURI("mongodb://localhost:27017"),)if err != nil {log.Fatal("连接失败:", err)}defer client.Disconnect(context.TODO()) // 确保关闭连接 // 2. 选择数据库和集合 db := client.Database("testdb")collection := db.Collection("users")// 3. 插入文档 user := User{Name: "张三", Email: "zhangsan@example.com",  Age: 28}insertResult, err := collection.InsertOne(context.TODO(), user)if err != nil {log.Fatal("插入失败:", err)}fmt.Printf("插入ID: %v\n", insertResult.InsertedID)// 4. 查询文档 filter := bson.D{{"name", "张三"}}var result User err = collection.FindOne(context.TODO(), filter).Decode(&result)if err != nil {log.Fatal("查询失败:", err)}fmt.Printf("查询结果: %+v\n", result)// 5. 更新文档 update := bson.D{{"$set", bson.D{{"age", 30}}}}updateResult, err := collection.UpdateOne(context.TODO(),filter,update,)if err != nil {log.Fatal("更新失败:", err)}fmt.Printf("更新数量: %d\n", updateResult.ModifiedCount)// 6. 删除文档 deleteResult, err := collection.DeleteOne(context.TODO(), filter)if err != nil {log.Fatal("删除失败:", err)}fmt.Printf("删除数量: %d\n", deleteResult.DeletedCount)
}```

http://www.ppmy.cn/server/176902.html

相关文章

OpenCV计算摄影学(23)艺术化风格化处理函数stylization()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 风格化的目的是生成不以照片写实为目标的多种多样数字图像效果。边缘感知滤波器是风格化处理的理想选择,因为它们能够弱化低对比度区…

Flutter Dart 异步支持全面解析

引言 在 Flutter 开发中,Dart 语言提供了强大的异步支持机制。异步编程能够让程序在执行耗时操作(如网络请求、文件读写等)时,不会阻塞主线程,从而保证用户界面的流畅性和响应性。本文将详细介绍 Dart 中常见的异步编…

人工智能实现电脑任务自动化的开源软件

人工智能实现电脑任务自动化的开源软件 hallo大家好,我是星哥,今天给大家介绍一个开源软件,融合了人工智能与机器人流程自动化(AIRPA)的开源软件autoMate! autoMate是什么 autoMate 是一款由开源开发的本地自动化工…

从零开始写C++3D游戏引擎(开发环境VS2022+OpenGL)之十一 从打光到材质 细嚼慢咽逐条读代码系列

写在篇前的话 作为一个曾经在代码堆里面苦苦挣扎的萌新,困惑的事情在于库,各种依赖,包换文件,链接库,纠结于代码的作用意义。尤其在3D引擎开发的问题上,很多人都被各种困难给阻拦,放弃了在3D渲染,3D游戏引擎上大涨鸿图的机会。 当然关于3D游戏引擎的教程已经汗牛充栋…

Spring MVC 拦截器使用

javaweb过滤器和springmvc拦截器: 拦截器的概念 拦截器使用 1/创建拦截器类,类中实现 handler执行前,执行后与渲染视图后的具体实现方法 public class GlobalExceptionHandler implements HandlerInterceptor {// if( ! preHandler()){re…

【CSS文字渐变动画】

CSS文字渐变动画 HTML代码CSS代码效果图 HTML代码 <div class"title"><h1>今天是春分</h1><p>正是春天到来的日子&#xff0c;花都开了&#xff0c;小鸟也飞回来了&#xff0c;大山也绿了起来&#xff0c;空气也有点嫩嫩的气息了</p>…

施磊老师c++(八)

语法 是 很不重要的, 基本的回会了就行了 cpp 面经 文章目录 cpp 面经1.程序的内存布局?--可以详看施磊老师第一节课2.堆栈区别3.函数调用参数是怎么传递的?4.为什么函数调用从右往左压栈5.函数题6.类和结构体的内存对齐----空结构体 1.程序的内存布局?–可以详看施磊老师第…

豪越科技消防一体化:数字中国智慧应急的关键支撑

在数字中国建设加速推进的当下&#xff0c;国家数据局对 2025 数字中国任务的部署&#xff0c;为各领域数字化转型指明了方向。其中&#xff0c;智慧应急作为保障城市安全运行的重要环节&#xff0c;备受关注。豪越科技消防一体化安全管控解决方案&#xff0c;凭借其先进的理念…