go-mongox: Generic Collection, Streamlined Document Operations, Efficient Build Bson, Plugin Programming
A Go Mongo package with streamlined document operations and efficient BSON data builder using generics.
What is go-mongox?
go-mongox is a generics-based library that extends the official MongoDB framework. Utilizing generic programming, it facilitates the binding of structs to MongoDB collections, aiming to provide type safety and streamlined data operations.
go-mongox introduces chainable calls for smoother document handling and offers a rich set of bson builders and built-in functions to simplify the build of bson data.
Moreover, it supports plugin-based programming and incorporates various hooks, offering flexibility for custom logic before and after database operations, thus enhancing the application's extensibility and maintainability.
Github: go-mongox
Contribute to go-mongox!
With your involvement, go-mongox will become even more powerful!
Feature Highlights
- Generic MongoDB Collection
- CRUD operations on documents
- Aggregation operations
- Built-in basic Model structure for automated updates of default field fields
- Support for building bson data
- Struct tags validation
- Hooks
- Plugin programming support
Installation
To install the go-mongox
module in your Go
application, execute the following command:
go get github.com/chenmingyong0423/go-mongox
Builders
go-mongox
has designed various types of BSON
builders and functions, providing robust support for developers constructing BSON
data in different scenarios. Whether it's for data queries, updates, or complex aggregation operations, developers can find suitable builders or functions in specialized packages such as bsonx
, query
, update
, and aggregation
. These BSON
builders and functions not only optimize the coding process but also significantly enhance development efficiency, making it simple and efficient to handle complex BSON
data.
Query Statement Construction - query package
The query
package provides convenient methods for building MongoDB
query conditions. It includes a series of functions and builders designed to simplify the construction of query conditions. For complex query conditions, builders offer flexible building methods through chainable calls; for simple needs, functions are available for quick construction.
Simple Construction
For a single query condition, we directly use functions to build.
// bson.D{bson.E{Key:"_id", Value:"12345678"}}
/*
{
"_id": "12345678"
}
*/
query.Id("12345678")
// bson.D{bson.E{Key:"name", Value:bson.D{bson.E{Key:"$in", Value:[]string{"Mingyong Chen", "chenmingyong"}}}}}
/*
{
"name": {
"$in": ["Mingyong Chen", "chenmingyong"]
}
}
*/
query.In("name", "Mingyong Chen", "chenmingyong")
// bson.D{bson.E{Key:"age", Value:bson.D{bson.E{Key:"$gte", Value:18}}}}
/*
{
"age": {
"$gte": 18
}
}
*/
query.Gte("age", 18)
// bson.D{bson.E{Key:"name", Value:bson.D{bson.E{Key:"$regex", Value:".*cmy.*"}, bson.E{Key:"$options", Value:"i"}}}}
/*
{
"name": {
"$regex": ".*cmy.*",
"$options": "i"
}
}
*/
query.RegexOptions("name", ".*cmy.*", "i")
The query
package's functions optimize the coding process, enhancing development efficiency.
For more details, please visit the official documentation: query package | go-mongox.
Complex Construction
For more complex BSON
data formats, we use builders for construction.
// bson.D{bson.E{Key:"age", Value:bson.D{bson.E{Key:"$gte", Value:18}, bson.E{Key:"$lte", Value:25}}}, bson.E{Key:"name", Value:bson.D{bson.E{Key:"$in", Value:[]interface {}{"Mingyong Chen", "chenmingyong"}}}}}
/*
{
"age": {
"$gte": 18,
"$lte": 25
},
"name": {
"$in": ["Mingyong Chen", "chenmingyong"]
}
}
*/
query.BsonBuilder().Gte("age", 18).Lte("age", 25).In("name", "Mingyong Chen", "chenmingyong").Build()
// bson.D{bson.E{Key:"lastLogin", Value:bson.D{bson.E{Key:"$gte", Value:time.Date(2024, time.March, 0, 0, 0, 0, 189625000, time.Local)}}}, bson.E{Key:"$or", Value:[]interface {}{bson.D{bson.E{Key:"status", Value:bson.D{bson.E{Key:"$eq", Value:"active"}}}}, bson.D{bson.E{Key:"loginAttempts", Value:bson.D{bson.E{Key:"$gte", Value:5}}}}}}}
/*
{
"lastLogin": {
"$gte": "2024-03-08T00:00:00.189Z"
},
"$or": [
{
"status": {
"$eq": "active"
}
},
{
"loginAttempts": {
"$gte": 5
}
}
]
}
*/
query.BsonBuilder().Gte("lastLogin", time.Now().Add(-30*24*time.Hour)).Or(
query.Eq("status", "active"),
query.Gte("loginAttempts", 5),
).Build()
// bson.D{bson.E{Key:"name", Value:bson.D{bson.E{Key:"$eq", Value:"Mingyong Chen"}}}, bson.E{Key:"hobbies", Value:bson.D{bson.E{Key:"$elemMatch", Value:primie.D{bson.E{Key:"name", Value:bson.D{bson.E{Key:"$eq", Value:"coding"}}}, bson.E{Key:"level", Value:bson.D{bson.E{Key:"$gte", Value:5}}}}}}}}
/*
{
"name": {
"$eq": "Mingyong Chen"
},
"hobbies": {
"$elemMatch": {
"name": {
"$eq": "coding"
},
"level": {
"$gte": 5
}
}
}
}
*/
query.BsonBuilder().
Eq("name", "Mingyong Chen").
ElemMatch("hobbies", query.BsonBuilder().Eq("name", "coding").Gte("level", 5).Build()).
Build()
Through these examples, we can see the power of builders, which use a chainable call approach to construct complex query statements. This method makes the code clearer, easier to read, maintain, and extend.
For more details, please visit the official documentation: query package | go-mongox.
Document Update Construction - update package
The update
package provides convenient methods for constructing MongoDB
update documents. It includes a series of functions and builders designed to simplify the construction of update documents. For complex update documents, builders offer flexible building methods through chainable calls; for simple needs, functions are available for quick construction.
Simple Construction
For a single update document, we directly use functions to build.
// bson.D{bson.E{Key:"$set", Value:bson.D{bson.E{Key:"name", Value:"Mingyong Chen"}}}}
/*
{
"$set": {
"name": "Mingyong Chen"
}
}
*/
update.Set("name", "Mingyong Chen")
// bson.D{bson.E{Key:"$inc", Value:bson.D{bson.E{Key:"money", Value:"100000"}}}}
/*
{
"$inc": {
"money": 100000
}
}
*/
update.Inc("money", "100000")
// bson.D{bson.E{Key:"$push", Value:bson.D{bson.E{Key:"tags", Value:"golang"}}}}
/*
{
"$push": {
"tags": "golang"
}
}
*/
update.Push("tags", "golang")
For more details, please visit the official documentation: update package | go-mongox.
Complex Construction
For more complex update documents, we use builders for construction.
// bson.D{bson.E{Key:"$set", Value:bson.D{bson.E{Key:"name", Value:"Mingyong Chen"}, bson.E{Key:"age", Value:18}}}}
/*{
"$set": {
"name": "Mingyong Chen",
"age": 18
}
}
*/
update.BsonBuilder().Set("name", "Mingyong Chen").Set("age", 18).Build()
// bson.D{bson.E{Key:"$set", Value:bson.D{bson.E{Key:"update_at", Value:time.Date(2024, time.April, 7, 3, 13, 23, 958924000, time.Local)}}}, bson.E{Key:"$inc", Value:bson.D{bson.E{Key:"view", Value:1}}}}
/*{
"$set": {
"update_at": "2024-04-07T00:00:00.958Z"
},
"$inc": {
"view": 1
}
}
*/
update.BsonBuilder().Set("update_at", time.Now()).Inc("view", 1).Build()
// bson.D{bson.E{Key:"$push", Value:bson.D{bson.E{Key:"comments", Value:"New Comment"}}}, bson.E{Key:"$inc", Value:bson.D{bson.E{Key:"commentCount", Value:}}}
/*
{
"$push": {
"comments": "New Comment"
},
"$inc": {
"commentCount": 1
}
}
*/
update.BsonBuilder().Push("comments", "New Comment").Inc("commentCount", 11).Build()
For more details, please visit the official documentation: update package | go-mongox.
Aggregation Pipeline Stages and Expression Construction - aggregation package
The aggregation
package provides convenient methods to construct MongoDB
aggregation pipelines (pipeline
). It includes multiple functions and builders, simplifying the pipeline construction process. For complex scenarios, builders support chainable calls, making the construction process more flexible; for basic needs, functions can quickly complete the construction.
The aggregation
package offers two types of builders:
aggregation.StageBuilder
: For easily constructing various stages of the aggregation pipeline, such as$group
,$match
, etc. Create a new builder instance withaggregation.StageBsonBuilder()
, then call the appropriate methods to build the stage.aggregation.Builder
: For constructing complex expressions used within pipeline stages, such as conditional logic, mathematical operations, etc. Create a new builder instance withaggregation.BsonBuilder()
, then call the appropriate methods to build the expression.
Aggregation Pipeline Stages
The aggregation stage builder is used for easily constructing various stages of the aggregation pipeline, such as $group
, $match
, etc.
Create a new builder instance with aggregation.StageBsonBuilder()
, then call the appropriate methods to build the stage.
type User struct {
mongox.Model `bson:"inline"`
Name string `bson:"name"`
Age int `bson:"age"`
}
// mongo.Pipeline{bson.D{bson.E{Key:"$group", Value:bson.D{bson.E{Key:"_id", Value:"$age"}, bson.E{Key:"count", Value:bson.D{bson.E{Key:"$sum", Value:1}}}, bson.E{Key:"names", Value:bson.D{bson.E{Key:"$push", Value:"$name"}}}}}}}
/*[
{
"$group": {
"_id": "$age",
"count": { "$sum": 1 },
"names": { "$push": "$name" }
}
}
]
*/
aggregation.StageBsonBuilder().Group("$age",
aggregation.BsonBuilder().Sum("count", 1).Push("names", "$name").Build()...,
).Build()
// mongo.Pipeline{bson.D{bson.E{Key:"$addFields", Value:bson.D{bson.E{Key:"isAdult", Value:bson.D{bson.E{Key:"$gte", Value:[]interface {}{"$age", 18}}}}}}}, bson.E{Key:"$replaceWith", Value:bson.D{bson.E{Key:"name", Value:"$name"}, bson.E{Key:"isAdult", Value:"$isAdult"}}}}}
/*
[
{
"$addFields": {
"isAdult": {
"$gte": ["$age", 18]
}
}
},
{
"$replaceWith": {
"name": "$name",
"isAdult": "$isAdult"
}
}
]
*/
aggregation.StageBsonBuilder().
AddFields(aggregation.Gte("isAdult", "$age", 18)).
ReplaceWith(bsonx.NewD().Add("name", "$name").Add("isAdult", "$isAdult").Build()).Build()
// mongo.Pipeline{bson.D{bson.E{Key:"$bucket", Value:bson.D{bson.E{Key:"groupBy", Value:"$age"}, bson.E{Key:"boundaries", Value:[]interface {}{0, 19, 31, 46, +Inf}}, bson.E{Key:"default", Value:"Other"}, bson.E{Key:"output", Value:bson.D{bson.E{Key:"count", Value:bson.D{bson.E{Key:"$sum", Value:1}}}, bson.E{Key:"names", Value:bson.D{bson.E{Key:"$push", Value:"$name"}}}}}}}}}
/*
[
{
$bucket: {
groupBy: "$age",
boundaries: [0, 19, 31, 46, Infinity],
default: "Other",
output: {
"count": { $sum: 1 },
"names": { $push: "$name" }
}
}
}
]
*/
aggregation.StageBsonBuilder().Bucket(
"$age",
[]any{0, 19, 31, 46, math.Inf(1)},
&types.BucketOptions{
DefaultKey: "Other",
Output: aggregation.BsonBuilder().Sum("count", 1).Push("names", "$name").Build(),
},
).Build()
For more details, please visit the official documentation: Aggregation Stage Builder | go-mongox.
Aggregation Expressions
The aggregation expression builder is used for easily constructing various expressions of the aggregation pipeline, such as $add
, $subtract
, etc.
Create a new builder instance with aggregation.BsonBuilder()
, then call the appropriate methods to build the expression.
Simple Construction
For a single expression, we directly use functions to build.
// bson.D{bson.E{Key:"isAdult", Value:bson.D{bson.E{Key:"$gte", Value:[]interface {}{"$age", 18}}}}}
/*
{
"isAdult": {
"$gte": ["$age", 18]
}
}
*/
aggregation.Gte("isAdult", "$age", 18)
// bson.D{bson.E{Key:"birthYear", Value:bson.D{bson.E{Key:"$subtract", Value:[]interface {}{2024, "$age"}}}}}
/*
{
"birthYear": {
"$subtract": [2024, "$age"]
}
}
*/
aggregation.Subtract("birthYear", 2024, "$age")
// bson.D{bson.E{Key:"age", Value:bson.D{bson.E{Key:"$gt", Value:[]interface {}{18}}}}}
/*
{
"age": {
"$gt": 18
}
}
*/
aggregation.Gt("age", 18)
For more details, please visit the official documentation: Aggregation Expression Builder | go-mongox.
Complex Construction
For more complex expressions, we use builders for construction.
// bson.D{bson.E{Key:"isAdult", Value:bson.D{bson.E{Key:"$gte", Value:[]interface {}{"$age", 18}}}}, bson.E{Key:"birthYear", Value:bson.D{bson.E{Key:"$subtract", Value:[]interface {}{2024, "$age"}}}}}
/*
{
"isAdult": {
"$gte": ["$age", 18]
},
"birthYear": {
"$subtract": [2024, "$age"]
}
}
*/
aggregation.BsonBuilder().
Gte("isAdult", "$age", 18).
Subtract("birthYear", 2024, "$age").Build()
// bson.D{bson.E{Key:"count", Value:bson.D{bson.E{Key:"$sum", Value:1}}}, bson.E{Key:"names", Value:bson.D{bson.E{Key:"$push", Value:"$name"}}}}
/*
{
"count": {
"$sum": 1
},
"names": {
"$push": "$name"
}
}
*/
aggregation.BsonBuilder().Sum("count", 1).Push("names", "$name").Build()
// bson.D{bson.E{Key:"count", Value:bson.D{bson.E{Key:"$sum", Value:1}}}, bson.E{Key:"averageAge", Value:bson.D{bson.E{Key:"$avg", Value:"$age"}}}, bson.E{Key:"names", Value:bson.D{bson.E{Key:"$push", Value:"$name"}}}}
/*{
"count": {
"$sum": 1
},
"averageAge": {
"$avg": "$age"
},
"names": {
"$push": "$name"
}
}
*/
aggregation.BsonBuilder().
Sum("count", 1).
Avg("averageAge", "$age").
Push("names", "$name").Build()
For more details, please visit the official documentation: Aggregation Expression Builder | go-mongox.
bsonx package: Simplifying BSON Data Construction
The bsonx
package offers a range of convenient functions and builders for constructing BSON
data, aimed at simplifying the BSON
data construction process.
Builder
Currently, the bsonx
package only provides a bson.D
data constructor, DBuilder
.
d := bsonx.NewD().Add("name", "Mingyong Chen").Add("name", "Burt")
Functions
Functions simplify the construction of BSON
data.
m := bsonx.M("name", "Mingyong Chen")
e := bsonx.E("name", "Mingyong Chen")
d := bsonx.D("name", "Mingyong Chen")
a := bsonx.A("Mingyong Chen", "Mingyong Chen")
For more details, please visit the official documentation: bsonx package | go-mongox.
Conclusion
This article provided a detailed introduction to the bson data construction
module within the go-mongox
library. go-mongox
has designed a variety of BSON
builders and functions, offering powerful support for developers constructing BSON
data in different scenarios.
Contribute to go-mongox!
With your involvement, go-mongox will become even more powerful!