GoFrame MongoDB 使用指南

GoFrame MongoDB 使用指南

1. 安装依赖

bash 复制代码
# 安装官方MongoDB驱动
go get -u go.mongodb.org/mongo-driver/mongo
go get -u go.mongodb.org/mongo-driver/mongo/options
go get -u go.mongodb.org/mongo-driver/bson

2. MongoDB 连接示例

go 复制代码
package main

import (
    "context"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func ConnectMongoDB() (*mongo.Client, error) {
    // 设置客户端连接配置
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    // 设置连接超时
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // 连接到MongoDB
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        return nil, err
    }

    // 验证连接
    err = client.Ping(ctx, nil)
    if err != nil {
        return nil, err
    }

    return client, nil
}

3. 数据操作示例

go 复制代码
package main

import (
    "context"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type User struct {
    ID       string    `bson:"_id,omitempty"`
    Username string    `bson:"username"`
    Email    string    `bson:"email"`
    Age      int       `bson:"age"`
    CreateAt time.Time `bson:"create_at"`
}

// 插入数据
func InsertUser(client *mongo.Client, user User) error {
    collection := client.Database("testdb").Collection("users")
    
    _, err := collection.InsertOne(context.Background(), user)
    return err
}

// 查询数据
func FindUserByUsername(client *mongo.Client, username string) (*User, error) {
    collection := client.Database("testdb").Collection("users")
    
    var user User
    err := collection.FindOne(context.Background(), bson.M{"username": username}).Decode(&user)
    if err != nil {
        return nil, err
    }
    
    return &user, nil
}

// 更新数据
func UpdateUser(client *mongo.Client, username string, update bson.M) error {
    collection := client.Database("testdb").Collection("users")
    
    _, err := collection.UpdateOne(
        context.Background(), 
        bson.M{"username": username},
        bson.M{"$set": update},
    )
    return err
}

// 删除数据
func DeleteUser(client *mongo.Client, username string) error {
    collection := client.Database("testdb").Collection("users")
    
    _, err := collection.DeleteOne(context.Background(), bson.M{"username": username})
    return err
}

// 复杂查询
func ComplexQuery(client *mongo.Client) ([]User, error) {
    collection := client.Database("testdb").Collection("users")
    
    // 查询年龄大于18的用户
    cursor, err := collection.Find(context.Background(), bson.M{
        "age": bson.M{"$gt": 18},
    })
    if err != nil {
        return nil, err
    }
    defer cursor.Close(context.Background())

    var users []User
    if err = cursor.All(context.Background(), &users); err != nil {
        return nil, err
    }

    return users, nil
}

4. 与GoFrame集成

虽然GoFrame的gdb不直接支持MongoDB,但你可以在GoFrame应用中使用官方MongoDB驱动:

go 复制代码
package service

import (
    "github.com/gogf/gf/v2/frame/g"
    "go.mongodb.org/mongo-driver/mongo"
)

type MongoService struct {
    client *mongo.Client
}

func (s *MongoService) Init() error {
    client, err := ConnectMongoDB()
    if err != nil {
        g.Log().Error(context.Background(), "MongoDB连接失败:", err)
        return err
    }
    s.client = client
    return nil
}

func (s *MongoService) GetCollection(dbName, collectionName string) *mongo.Collection {
    return s.client.Database(dbName).Collection(collectionName)
}

5. 注意事项

  1. 使用官方MongoDB驱动
  2. 正确管理数据库连接
  3. 使用上下文(Context)控制超时
  4. 添加适当的错误处理
  5. 考虑连接池和性能优化

6. 复杂查询示例

go 复制代码
// 复杂条件查询
func ComplexQuery(ctx context.Context) {
    // 年龄大于18且邮箱域名为gmail的用户
    users, err := g.Model("users").Ctx(ctx).
        Where("age", ">", 18).
        WhereLike("email", "%@gmail.com").
        Order("create_at DESC").
        Limit(10).
        All()
    
    // 聚合查询
    result, err := g.Model("users").Ctx(ctx).
        Fields("age", "COUNT(*) as count").
        Group("age").
        Having("count > 5").
        All()
}

7. 事务处理

go 复制代码
func TransactionExample(ctx context.Context) error {
    return g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
        // 执行多个数据库操作
        _, err1 := tx.Model("users").Data(g.Map{
            "username": "newuser",
            "email":    "[email protected]",
        }).Insert()

        _, err2 := tx.Model("logs").Data(g.Map{
            "action": "user_created",
        }).Insert()

        // 任何一个操作失败都会回滚
        if err1 != nil || err2 != nil {
            return errors.New("transaction failed")
        }
        return nil
    })
}

8. 性能优化建议

  • 使用索引
  • 避免返回大量数据
  • 使用投影减少网络传输
  • 合理使用缓存

9. 错误处理

go 复制代码
func ErrorHandling(ctx context.Context) {
    user, err := dao.User.FindByUsername(ctx, "example")
    if err != nil {
        switch {
        case err == g.ErrRecordNotFound:
            // 处理未找到记录
            g.Log().Error(ctx, "User not found")
        case g.IsDBError(err):
            // 处理数据库错误
            g.Log().Error(ctx, "Database error:", err)
        default:
            // 其他未知错误
            g.Log().Error(ctx, "Unexpected error:", err)
        }
    }
}

总结

GoFrame 提供了强大且简洁的 MongoDB 操作方式,通过抽象层屏蔽了底层实现细节,使开发者可以专注于业务逻辑。

相关推荐
我有医保我先冲1 分钟前
SQL复杂查询与性能优化全攻略
数据库·sql·性能优化
烧瓶里的西瓜皮11 分钟前
Go语言从零构建SQL数据库引擎(2)
数据库·sql·golang
SelectDB27 分钟前
拉卡拉 x Apache Doris:统一金融场景 OLAP 引擎,查询提速 15 倍,资源直降 52%
大数据·数据库·数据分析
爱的叹息29 分钟前
华为高斯(GaussDB) 集中式数据库 的开发技术手册,涵盖核心功能、开发流程、优化技巧及常见问题解决方案
数据库·gaussdb
背太阳的牧羊人33 分钟前
使用 PyMuPDF(fitz)库打开 PDF 文件,并且是从内存中的字节流(BytesIO)读取 PDF 内容
数据库·pdf·文件处理·pymupdf·fitz
@淡 定2 小时前
MySQL MVCC 机制解析
数据库·mysql
Chandler242 小时前
Redis:内存淘汰原则,缓存击穿,缓存穿透,缓存雪崩
数据库·redis·缓存
SRC_BLUE_172 小时前
Python GUI 编程 | QObject 控件基类详解 — 定时器
开发语言·数据库·python
DBWYX2 小时前
MySQL 进阶 面经级
数据库·mysql
喝醉酒的小白3 小时前
SQL Server:触发器
数据库