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":    "newuser@example.com",
        }).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 操作方式,通过抽象层屏蔽了底层实现细节,使开发者可以专注于业务逻辑。

相关推荐
ltl1 小时前
RocksDB 并发 Compaction 与 Rate Limiter
数据库
闻道且行之2 小时前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
夏炳辉.3 小时前
PostgreSQL 高可用集群核心配置参数全解:从原生流复制到 Patroni 企业级方案
数据库·postgresql
努力的小雨4 小时前
KES 开启 SSL 前,证书、端口和客户端要一起验
数据库
DevOps老兵4 小时前
AI全栈知识07:向量数据库 - Milvus/Chroma实战
数据库·ai·milvus
这个DBA有点耶4 小时前
当数据库从“存储”走向“决策”:金仓数据库的融合架构之路
数据库·架构·aigc
smilejingwei5 小时前
Trae+SQLazy 实践 SQL 国产化移植:Oracle => 达梦
数据库·sql·oracle
意疏5 小时前
2026年远控软件安全横评:六款主流工具逐项核查——官方文档、一手实测与安全事件,全摊开
大数据·前端·数据库
名不经传的养虾人6 小时前
从0到1:企业级AI项目迭代日记 Vol.90|Agent变快了,Judge定下来了
大数据·数据库·人工智能·ai编程·企业ai
冰之杍6 小时前
MySQL utf8mb3 → utf8mb4 完整修改方案
数据库·mysql