friendlymongo
MongoDB for Golang made easy (maybe).
friendlymongo aims to make working with MongoDB in Go:
- Simpler — minimal boilerplate
- Readable — fluent builder patterns
- Practical — integrates cleanly with idiomatic Go
📦 Installation
go get -u github.com/pmatteo/friendlymongo
Note: >
friendlymongois tested with Go versions1.18and1.22, using different MongoDB versions.
🚀 Usage
A simple example is available here.
🧩 Client
friendlymongo provides an easy way to manage a mongo.Client instance as a singleton.
- Use
SetInstance(url)to initialize it. - Retrieve it anywhere using
GetInstance().
The wrapper type MongoClient exposes convenient helpers:
Client()→ returns themongo.ClientinstanceDatabase(dbName)→ returns a newmongo.Databaseinstance
Example
i := friendlymongo.SetInstance("mongodb://username:password@localhost:27017")
c := i.Client()
db := i.Database("user")
or equivalently:
friendlymongo.SetInstance("mongodb://username:password@localhost:27017")
c := friendlymongo.GetInstance().Client()
db := friendlymongo.GetInstance().Database("user")
🧱 Model
The Model interface defines lifecycle hooks for any struct intended for repository usage.
type Model interface {
OnCreate()
OnUpdate()
OnReplace()
}
A convenient BaseModel is included, which automatically handles:
- MongoDB
ObjectID created_atandupdated_attimestamps
Example
type UserProfile struct {
*friendlymongo.BaseModel
Name string
Surname string
Email string
BirthDate time.Time
}
🗂 Repository
The core purpose of friendlymongo is to simplify MongoDB access in Go, eliminating repetitive boilerplate.
The repository pattern is implemented using Go generics, providing out-of-the-box CRUD operations for your model type.
Example
// Retrieve a BaseRepository instance for the UserProfile type
repo := friendlymongo.NewBaseRepository(db, "userProfile", &UserProfile{})
user := NewUserProfile("John", "Doe", "john.doe@test.com", birthday)
// Insert the user into the database
if err := repo.InsertOne(context.Background(), user); err != nil {
panic(err)
}
🧮 Pipeline Stage Builder
BaseRepository provides an Aggregate() method that accepts a mongo.Pipeline.
To simplify pipeline creation, friendlymongo includes a stage builder — a fluent, structured way to define aggregation stages.
Example
pipeline := friendlymongo.
NewStageBuilder().
Match("name_filter", bson.M{"name": "John"}).
Lookup("roles_lookup", "user_role", "_id", "fk", "role").
Match("filter_admin", bson.M{"role.name": "admin"}).
Build()
The builder includes helpers for several common stages.
You can also add custom stages using the AddStage() method.
⚙️ Operators
friendlymongo includes simplified helpers for some MongoDB operators such as $push and $map.
More will be added over time.
Example
fm.NewStageBuilder().
Lookup("product_lookup", "product", "products", "ean", "products").
Unwind("unwind_products", "$products").
Group("category_id_group", bson.M{
"_id": bson.M{
"orderId": "$_id",
"category": "$products.category",
},
"status": fm.First("$status"),
"products": fm.Push("$products"),
}).
Group("productsByCategory", bson.M{
"_id": "$_id.orderId",
"status": fm.First("$status"),
"productsByCategory": fm.Push("category", "$_id.category", "products", "$products"),
}).
Project("final_project", bson.M{
"_id": 1,
"status": 1,
"grouped_products": fm.ArrayToObject(
fm.Map("$productsByCategory", "cat", "$$cat.category", "$$cat.products"),
),
})