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 globalqmgo.Clientmap (qmMDBMap), buildsqmgo.Configfrom environment variables, and provides thegetColl()helper to obtainqmgo.Collectioninstances.domainx/connect.go: Extends the genericConstruct with aMongoDB *qmgo.Clientfield, 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.goanddomainx/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.gohandlesqmgo.Clientlifecycle and connection pooling viaUseMongoDbConn(), caching clients inqmMDBMapby database name. - Connection Structs: Extend
domainx.Con(as shown indomainx/connect.go) to includeMongoDB *qmgo.Clientfor domain-specific models. - Collection Access: Use
domainx.GetColl()to retrieveqmgo.Collectioninstances without manual database/collection name management; errors are wrapped using Gorig's standard error utilities. - Driver Agnostic: The
domainxpackage 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →