How to Integrate MongoDB Using qmgo in Gorig: Complete Implementation Guide

You can integrate MongoDB in Gorig by initializing a qmgo client via domainx.UseMongoDbConn(), embedding it in a struct that extends domainx.Con, and using the provided collection helpers to perform CRUD operations.

Gorig's persistence layer abstracts database drivers behind the domainx package, enabling seamless switching between SQL and NoSQL backends. To integrate MongoDB using qmgo in Gorig, you leverage the official qmgo driver (github.com/qiniu/qmgo) wrapped in Gorig's connection management system. This architecture isolates MongoDB-specific connection logic while preserving driver-agnostic business logic in your service layer.

Gorig's MongoDB Architecture Components

Gorig implements MongoDB support through four key files in the domainx package that manage connection lifecycle and abstract CRUD operations.

Core Files and Responsibilities

  • domainx/db.qmo.go: Manages the global qmgo.Client map (qmMDBMap), builds qmgo.Config from environment variables, and provides the getColl() helper to obtain qmgo.Collection instances.
  • domainx/connect.go: Extends the generic Con struct with a MongoDB *qmgo.Client field, allowing domain models to carry MongoDB connections alongside other database handles.
  • domainx/db.extend.go: Supplies common CRUD helpers that work with both Gorm (SQL) and qmgo (MongoDB) operations behind unified interfaces.
  • domainx/service.go and domainx/api.go: Demonstrate how service layers consume these connections to execute business logic against MongoDB collections.

Step-by-Step Integration Guide

Integrating MongoDB follows a three-phase pattern: client initialization, connection configuration, and CRUD execution.

Initialize the qmgo Client

Create the global MongoDB client using UseMongoDbConn(). According to domainx/db.qmo.go, this function reads configuration from environment variables (such as GORIG_MONGO_URI) and stores the initialized client in an internal map for reuse.

// bootstrap/startup.go
import (
    "fmt"
    "github.com/jom-io/gorig/domainx"
    "github.com/qiniu/qmgo"
)

func InitMongo() (*qmgo.Client, error) {
    // UseMongoDbConn creates and caches the client for database "mydb"
    client := domainx.UseMongoDbConn("mydb")
    if client == nil {
        return nil, fmt.Errorf("failed to create qmgo client")
    }
    return client, nil
}

Configure the Domain Connection

Create a domain-specific connection struct that embeds domainx.Con and carries the MongoDB client. As defined in domainx/connect.go, the Con struct extension allows your services to access collection handles through Gorig's helper functions.

// models/connection.go
type MyCon struct {
    domainx.Con           // Embeds generic connection fields (DBName, Collection, etc.)
    MongoDB *qmgo.Client   // Populated via connect.go extension
}

func NewMyCon() *MyCon {
    c := &MyCon{}
    c.DBName = "mydb"
    c.Collection = "users"
    // Attach the global MongoDB client for this database
    c.MongoDB = domainx.UseMongoDbConn(c.DBName)
    return c
}

Perform CRUD Operations

Use domainx.GetColl() (which internally calls getColl() from domainx/db.qmo.go) to retrieve a qmgo.Collection pointer, then execute standard qmgo methods. Error handling leverages Gorig's utils/errors package for consistent error wrapping.

// services/user_service.go
func (svc *UserService) FindByID(ctx context.Context, id string) (*User, error) {
    con := NewMyCon()
    coll, err := domainx.GetColl(con) // Returns *qmgo.Collection
    if err != nil {
        return nil, err
    }

    var u User
    filter := bson.M{"_id": id}
    if err := coll.Find(ctx, filter).One(&u); err != nil {
        return nil, err
    }
    return &u, nil
}

Insert Documents

The same connection pattern applies to write operations. The InsertOne() method and other mutators work directly with the collection handle returned by Gorig's helpers, as shown in domainx/db.extend.go.

// services/user_service.go
func (svc *UserService) Create(ctx context.Context, u *User) error {
    con := NewMyCon()
    coll, err := domainx.GetColl(con)
    if err != nil {
        return err
    }
    _, err = coll.InsertOne(ctx, u)
    return err
}

Driver Portability

Gorig's architecture abstracts the underlying database driver behind the domainx interfaces. To switch from Gorm (SQL) to qmgo (MongoDB), change the configuration flag that selects the driver in your environment. Your service method signatures and business logic remain unchanged because domainx/db.extend.go provides common CRUD wrappers for both drivers.

Summary

  • Client Management: domainx/db.qmo.go handles qmgo.Client lifecycle and connection pooling via UseMongoDbConn(), caching clients in qmMDBMap by database name.
  • Connection Structs: Extend domainx.Con (as shown in domainx/connect.go) to include MongoDB *qmgo.Client for domain-specific models.
  • Collection Access: Use domainx.GetColl() to retrieve qmgo.Collection instances without manual database/collection name management; errors are wrapped using Gorig's standard error utilities.
  • Driver Agnostic: The domainx package abstracts CRUD operations, allowing seamless switching between Gorm and qmgo without modifying service layer code.

Frequently Asked Questions

How does Gorig manage multiple MongoDB databases?

Gorig maintains a global map (qmMDBMap) in domainx/db.qmo.go that caches qmgo.Client instances by database name. When you call UseMongoDbConn(dbname), it returns the cached client for that specific database, enabling multi-database support without recreating connections.

Can I use native qmgo features within Gorig's framework?

Yes. Since domainx.GetColl() returns a standard *qmgo.Collection from the official qmgo driver, you have full access to native methods like Find(), InsertOne(), UpdateOne(), and aggregation pipelines. Gorig wraps connection management, not the driver API.

What configuration options does Gorig support for MongoDB connections?

According to the source code in domainx/db.qmo.go, Gorig builds qmgo.Config from environment variables including the MongoDB URI, authentication credentials, and connection pool settings. You customize these via the environment before calling UseMongoDbConn().

How do I handle connection errors in the MongoDB integration?

Gorig wraps connection errors using its internal utils/errors package. When getColl() or connection helpers encounter issues, they return wrapped errors that include context about the database name and collection, making debugging straightforward while maintaining consistent error handling across SQL and MongoDB drivers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →