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

> Integrate MongoDB in Gorig using qmgo. Discover how to initialize the client, embed it in your structs, and perform CRUD operations with this complete implementation guide.

- Repository: [Jom/gorig](https://github.com/jom-io/gorig)
- Tags: how-to-guide
- Published: 2026-03-04

---

**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`](https://github.com/jom-io/gorig/blob/main/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`](https://github.com/jom-io/gorig/blob/main/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`](https://github.com/jom-io/gorig/blob/main/domainx/db.extend.go)**: Supplies common CRUD helpers that work with both Gorm (SQL) and qmgo (MongoDB) operations behind unified interfaces.
- **[`domainx/service.go`](https://github.com/jom-io/gorig/blob/main/domainx/service.go) and [`domainx/api.go`](https://github.com/jom-io/gorig/blob/main/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`](https://github.com/jom-io/gorig/blob/main/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.

```go
// 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`](https://github.com/jom-io/gorig/blob/main/domainx/connect.go), the `Con` struct extension allows your services to access collection handles through Gorig's helper functions.

```go
// 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`](https://github.com/jom-io/gorig/blob/main/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.

```go
// 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`](https://github.com/jom-io/gorig/blob/main/domainx/db.extend.go).

```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`](https://github.com/jom-io/gorig/blob/main/domainx/db.extend.go) provides common CRUD wrappers for both drivers.

## Summary

- **Client Management**: [`domainx/db.qmo.go`](https://github.com/jom-io/gorig/blob/main/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`](https://github.com/jom-io/gorig/blob/main/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`](https://github.com/jom-io/gorig/blob/main/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`](https://github.com/jom-io/gorig/blob/main/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.