mongox
is a high-level MongoDB interface for Go that simplifies database operations and provides rich error handling. It wraps the official MongoDB Go driver to reduce boilerplate code and make MongoDB operations more intuitive.
Whether you are building small applications or large-scale systems, mongox
streamlines your database operations, allowing you to focus on what truly matters—developing your application.
- Simplified Interface: Reduce boilerplate code with an intuitive API.
- Rich Error Handling: Error types for all possible error codes
- Concurrent Safety: Designed for safe use across multiple goroutines.
- Well tested code: Built on top of official MongoDB Go driver,
mongox
has a 80% test coverage with integration tests using real MongoDB instance.
go get -u github.com/maxbolgarin/mongox
Before performing any operations, initialize a Collection
instance:
cfg := mongox.Config{
AppName: "MyApp",
Address: "localhost:27017",
Auth: &mongox.AuthConfig{
Username: "username",
Password: "password",
},
// TODO: other settings
}
client, err := mongox.Connect(ctx, cfg)
if err != nil {
return err
}
defer client.Disconnect(ctx) // TODO: handle error
db := client.Database("mydb")
collection := db.Collection("users")
Insert single or multiple documents into the collection:
type User struct {
Name string `bson:"name"`
Age int `bson:"age"`
}
user := User{Name: "Alice", Age: 30}
// Insert a single document
_, err := collection.Insert(ctx, user)
if err != nil {
return err
}
// Insert multiple documents
_, err = collection.Insert(ctx,
User{Name: "Bob", Age: 30},
User{Name: "Charlie", Age: 35},
)
if err != nil {
return err
}
// Insert with generic method
_, err = mongox.Insert(ctx, collection, User{Name: "Mike", Age: 20})
if err != nil {
return err
}
Get documents from the collection:
// Define a filter
filter := mongox.M{"age": mongox.Gt(20)}
// Find multiple documents
var users []mongox.User
err = collection.Find(ctx, &users, filter)
if err != nil {
return err
}
// Find a one document with a generic method and applied sort
result, err := mongox.FindOne[User](ctx, collection, filter, mongox.FindOptions{
Sort: mongox.M{"age": 1},
})
if err != nil {
return err
}
Modify existing documents in the collection. You can redefine mongox.M
to make code cleaner:
type M = mongox.M
update := M{
mongox.Inc: M{
"age": 1,
},
}
// Update a single document
err := collection.UpdateOne(ctx, filter, update)
if err != nil {
return err
}
// Set new fields
err := collection.SetFields(ctx, filter, M{"new_field": "value"})
if err != nil {
return err
}
// Upsert a document (update or insert)
record := User{
Name: "Diana",
Age: 28,
}
_, err = collection.Upsert(ctx, record, M{"name": "Alice"})
if err != nil {
return err
}
Remove documents from the collection:
// Delete a single document
err := collection.DeleteOne(ctx, M{"name": "Diana"})
if err != nil {
return err
}
// Delete multiple documents
n, err = collection.DeleteMany(ctx, M{"age": mongox.Lt(30)})
if err != nil {
return err
}
Create indexes to optimize query performance.
// Create a unique index on the 'email' field
err := collection.CreateIndex(ctx, true, "email")
if err != nil {
return err
}
// Create a text index for text search on 'name' and 'bio' fields
err = collection.CreateTextIndex(ctx, "en", "name", "bio")
if err != nil {
return err
}
mongox
provides error handling:
err := collection.Insert(ctx, User{
Name: eveName,
Age: eveAge,
})
if err != nil {
if errors.Is(err, mongox.ErrNotFound) {
// Handle not found
} else if errors.Is(err, mongox.ErrInvalidArgument) {
// Handle invalid argument
} else {
// Handle other errors
}
}
mongox
supports asynchronous operations using AsyncCollection
:
asyncCollection := client.AsyncDatabase("mydb").AsyncCollection("users")
// Insert a document asynchronously
asyncCollection.Insert("users_queue", "insert_task", User{
Name: "Alice",
Age: 30,
})
- Operations with the same queue name (first argument,
users_queue
in example) will be executed sequentially in strict order of calling - Operations with different queue names will be executed in parallel
- Name is using for logging.
Contributions are welcome! Please feel free to submit a Pull Request or an Issue.
This project is licensed under the terms of the MIT License.