golang官方MongoDB数据库驱动插件库mongo-go-driver的使用
Golang官方MongoDB数据库驱动插件库mongo-go-driver的使用
MongoDB官方支持的Go语言驱动程序。
要求
- Go 1.19或更高版本。我们旨在支持Go的最新版本。
- 运行驱动程序测试套件需要Go 1.23或更高版本。
- MongoDB 4.0及更高版本。
安装
推荐使用Go模块在项目中安装依赖:
go get go.mongodb.org/mongo-driver/v2/mongo
使用示例
基本连接
import (
"context"
"time"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"go.mongodb.org/mongo-driver/v2/mongo/readpref"
)
// 创建客户端连接
client, _ := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017"))
// 确保断开连接
defer func() {
if err = client.Disconnect(ctx); err != nil {
panic(err)
}
}()
// 检查连接
ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
_ = client.Ping(ctx, readpref.Primary())
插入文档
import (
"go.mongodb.org/mongo-driver/v2/bson"
)
// 获取集合
collection := client.Database("testing").Collection("numbers")
// 插入文档
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
res, _ := collection.InsertOne(ctx, bson.D{{"name", "pi"}, {"value", 3.14159}})
id := res.InsertedID
查询文档
// 查询多个文档
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
cur, err := collection.Find(ctx, bson.D{})
if err != nil {
log.Fatal(err)
}
defer cur.Close(ctx)
for cur.Next(ctx) {
var result bson.D
if err := cur.Decode(&result); err != nil {
log.Fatal(err)
}
// 处理结果...
}
if err := cur.Err(); err != nil {
log.Fatal(err)
}
// 查询单个文档
var result struct {
Value float64
}
filter := bson.D{{"name", "pi"}}
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err = collection.FindOne(ctx, filter).Decode(&result)
if errors.Is(err, mongo.ErrNoDocuments) {
// 没有找到记录的处理
} else if err != nil {
log.Fatal(err)
}
网络压缩
网络压缩可以减少MongoDB和应用程序之间的带宽需求。Go驱动程序支持以下压缩算法:
- Snappy (
snappy
): MongoDB 3.4及更高版本可用 - Zlib (
zlib
): MongoDB 3.6及更高版本可用 - Zstandard (
zstd
): MongoDB 4.2及更高版本可用
可以通过连接字符串参数或使用ClientOptions.SetCompressors
启用压缩:
// 通过连接字符串设置压缩
opts := options.Client().ApplyURI("mongodb://localhost:27017/?compressors=snappy,zlib,zstd")
client, _ := mongo.Connect(opts)
// 或通过ClientOptions设置
opts := options.Client().SetCompressors([]string{"snappy", "zlib", "zstd"})
client, _ := mongo.Connect(opts)
完整示例
package main
import (
"context"
"errors"
"log"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"go.mongodb.org/mongo-driver/v2/mongo/readpref"
)
func main() {
// 创建客户端连接
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)
}
}()
// 检查连接
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if err := client.Ping(ctx, readpref.Primary()); err != nil {
log.Fatal(err)
}
// 获取集合
collection := client.Database("test").Collection("numbers")
// 插入文档
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
res, err := collection.InsertOne(ctx, bson.D{{"name", "pi"}, {"value", 3.14159}})
if err != nil {
log.Fatal(err)
}
log.Println("Inserted ID:", res.InsertedID)
// 查询文档
var result struct {
Value float64 `bson:"value"`
}
filter := bson.D{{"name", "pi"}}
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err = collection.FindOne(ctx, filter).Decode(&result)
if errors.Is(err, mongo.ErrNoDocuments) {
log.Println("No document found")
} else if err != nil {
log.Fatal(err)
}
log.Println("Found value:", result.Value)
}
反馈与贡献
- 获取帮助请访问MongoDB社区论坛
- 报告新功能和错误请访问JIRA项目页面
- 贡献指南请参考项目文档
更多关于golang官方MongoDB数据库驱动插件库mongo-go-driver的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang官方MongoDB数据库驱动插件库mongo-go-driver的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用mongo-go-driver操作MongoDB
mongo-go-driver是MongoDB官方提供的Go语言驱动程序,提供了全面的MongoDB操作功能。下面我将介绍其基本用法和常见操作示例。
安装
首先安装mongo-go-driver:
go get go.mongodb.org/mongo-driver/mongo
基本连接
package main
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func main() {
// 设置连接选项
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
// 连接到MongoDB
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatal(err)
}
// 检查连接
err = client.Ping(ctx, readpref.Primary())
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to MongoDB!")
// 断开连接
defer func() {
if err = client.Disconnect(ctx); err != nil {
log.Fatal(err)
}
}()
}
CRUD操作
1. 插入文档
type Person struct {
Name string
Age int
City string
Hobbies []string
}
// 获取集合
collection := client.Database("testdb").Collection("people")
// 插入单个文档
person := Person{"张三", 30, "北京", []string{"游泳", "读书"}}
insertResult, err := collection.InsertOne(ctx, person)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted a single document: ", insertResult.InsertedID)
// 插入多个文档
persons := []interface{}{
Person{"李四", 25, "上海", []string{"跑步", "音乐"}},
Person{"王五", 28, "广州", []string{"旅游", "摄影"}},
}
insertManyResult, err := collection.InsertMany(ctx, persons)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
2. 查询文档
// 查询单个文档
var result Person
err = collection.FindOne(ctx, bson.M{"name": "张三"}).Decode(&result)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found a single document: %+v\n", result)
// 查询多个文档
cursor, err := collection.Find(ctx, bson.M{"age": bson.M{"$gt": 25}})
if err != nil {
log.Fatal(err)
}
defer cursor.Close(ctx)
var people []Person
if err = cursor.All(ctx, &people); err != nil {
log.Fatal(err)
}
fmt.Println("Found multiple documents:")
for _, p := range people {
fmt.Printf("%+v\n", p)
}
3. 更新文档
// 更新单个文档
filter := bson.M{"name": "张三"}
update := bson.M{
"$set": bson.M{
"age": 31,
"city": "深圳",
},
}
updateResult, err := collection.UpdateOne(ctx, filter, update)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Matched %v documents and updated %v documents.\n",
updateResult.MatchedCount, updateResult.ModifiedCount)
// 更新多个文档
updateManyResult, err := collection.UpdateMany(
ctx,
bson.M{"age": bson.M{"$gt": 25}},
bson.M{"$inc": bson.M{"age": 1}},
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Matched %v documents and updated %v documents.\n",
updateManyResult.MatchedCount, updateManyResult.ModifiedCount)
4. 删除文档
// 删除单个文档
deleteResult, err := collection.DeleteOne(ctx, bson.M{"name": "王五"})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Deleted %v documents\n", deleteResult.DeletedCount)
// 删除多个文档
deleteManyResult, err := collection.DeleteMany(ctx, bson.M{"age": bson.M{"$gt": 30}})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Deleted %v documents\n", deleteManyResult.DeletedCount)
高级操作
事务
session, err := client.StartSession()
if err != nil {
log.Fatal(err)
}
defer session.EndSession(ctx)
err = mongo.WithSession(ctx, session, func(sc mongo.SessionContext) error {
if err = session.StartTransaction(); err != nil {
return err
}
// 执行事务操作
if _, err = collection.InsertOne(sc, Person{"赵六", 35, "杭州", nil}); err != nil {
session.AbortTransaction(sc)
return err
}
if _, err = collection.UpdateOne(
sc,
bson.M{"name": "张三"},
bson.M{"$set": bson.M{"age": 32}},
); err != nil {
session.AbortTransaction(sc)
return err
}
return session.CommitTransaction(sc)
})
if err != nil {
log.Fatal(err)
}
聚合查询
matchStage := bson.D{{"$match", bson.D{{"age", bson.D{{"$gt", 25}}}}}}
groupStage := bson.D{
{"$group", bson.D{
{"_id", "$city"},
{"total", bson.D{{"$sum", 1}}},
{"averageAge", bson.D{{"$avg", "$age"}}},
}},
}
cursor, err := collection.Aggregate(ctx, mongo.Pipeline{matchStage, groupStage})
if err != nil {
log.Fatal(err)
}
defer cursor.Close(ctx)
var results []bson.M
if err = cursor.All(ctx, &results); err != nil {
log.Fatal(err)
}
for _, result := range results {
fmt.Printf("City: %v, Count: %v, Avg Age: %v\n",
result["_id"], result["total"], result["averageAge"])
}
最佳实践
- 连接池管理:客户端会自动管理连接池,通常一个应用只需要一个客户端实例
- 上下文使用:所有操作都应使用context来控制超时和取消
- BSON处理:使用
bson
标签定义结构体字段与MongoDB字段的映射关系 - 错误处理:检查所有操作返回的错误
- 资源释放:确保关闭游标和会话等资源
mongo-go-driver提供了丰富的功能,可以满足大多数MongoDB操作需求。更多高级用法可以参考官方文档。