English | 中文
A secondary encapsulation based on the official MongoDB Go driver.
- Call chain operations, freely combine conditions
- User-friendly API
- Support for Context
- Out-of-the-box functionality
- Pagination query support
- Easy aggregation support
- Database Management Command Operations
- Debug mode, supports generating native MongoDB statements.
- monitor support
- Command-line tool
- Continuously being updated
go get -u github.com/here-Leslie-Lau/mongo-plus
Create MongoDB Connection
opts := []mongo.Option{
// Database to Connect
mongo.WithDatabase("test"),
// Maximum Connection Pool Size
mongo.WithMaxPoolSize(10),
// Username
mongo.WithUsername("your username"),
// Password
mongo.WithPassword("your password"),
// Connection URL
mongo.WithAddr("localhost:27017"),
}
conn, f := mongo.NewConn(opts...)
defer f()
Add monitor support
monitor := &event.CommandMonitor{
Started: func(_ context.Context, evt *event.CommandStartedEvent) {
fmt.Println("start")
},
Succeeded: func(_ context.Context, evt *event.CommandSucceededEvent) {
fmt.Println("success")
},
}
opts = append(opts, mongo.WithMonitor(monitor))
conn, f := mongo.NewConn(opts...)
defer f()
The current monitor support includes *event.CommandMonitor, *event.PoolMonitor, *event.ServerMonitor
. For more use cases, refer to test/monitor_test.go.
Get Collection Object
type Demo struct{}
// Collection Implement the mongo.Collection interface, returning the name of the collection to operate on.
func (d *Demo) Collection() string {
return "demo"
}
// Get the collection object within the method.
demo := &Demo{}
coll := conn.Collection(demo)
Context Support
coll = coll.WithCtx(ctx)
Insert Document
coll.InsertOne(document)
coll.InsertMany(documents)
Query Documents
// Query a Single Document with the name "leslie"
coll.Where("name", "leslie").FindOne(&document)
// Query Documents with the name "leslie"
coll.Where("name", "leslie").Find(&documents)
// Multi-Condition Query
coll.Filter(map[string]interface{}{"name": "leslie", "age": 18}).FindOne(&document)
Query the Number of Documents that Meet the Criteria
// Count of Documents with the name "leslie"
cnt, err := coll.Where("name", "leslie").Count()
Sorting
// Query Ascending by the "value" Field
coll.Sort(mongo.SortRule{Typ: mongo.SortTypeASC, Field: "value"}).Find(&documents)
Pagination
f := &mongo.PageFilter{
// Current Page of the Query
PageNum: 1,
// Number of Items per Page
PageSize: 2,
}
// Place matching documents into the "documents" based on the criteria and place the total count and total pages into the "f".
coll.Paginate(f, &documents)
Logical Operations
// Find a Single Record with age Greater Than 18
coll.Gt("age", 18).FindOne(&document)
// Find a Single Record with age Less Than 18
coll.Lt("age", 18).FindOne(&document)
// Find a Single Record with age Greater Than or Equal to 18
coll.Gte("age", 18).FindOne(&document)
// Find a Single Record where age is Not Equal to 100
coll.NotEq("age", 100).FindOne(&document)
// ...other methods can be referenced in mongo/chain_cond.go
Specify the Fields to Query
// Query Results Only Assign to the "name" Field, After Calling This Method, the "_id" Field Is Not Assigned by Default
coll.Projection("name").Find(&documents)
Update or Insert a Record
// Update the age Field to 18
content := map[string]interface{}{"age": 18}
// Default Values to Insert if the Filter Criteria Do Not Exist
default := map[string]interface{}{"name": "leslie"}
conn.Where("name", "leslie").UpsertOne(content, default)
// Desired Outcome: If a document with name "leslie" exists, update the age to 18; otherwise, insert a document {"name": "leslie", "age": 18}.
OR Query (Logical OR Operation Query)
// Single Condition
orMap := map[string]interface{}{"age": 18, "name": "leslie"}
// Query Documents where name is "leslie" or age is 18
conn.Or(orMap).Find(&documents)
// Multiple Conditions
orMap1 := map[string]interface{}{"name": "leslie", "age": 22}
orMap2 := map[string]interface{}{"name": "skyle", "age": 78}
// Query Documents where name is "leslie" and age is 22, or name is "skyle" and age is 78.
conn.Ors(orMap1, orMap2).Find(&documents)
Debug mode
// output: db.xxx.findOne({"name": "leslie"})
conn.Debug(os.Stdout).Where("name", "leslie").FindOne(res)
Database Management Command Operations
Additional documentation can be found in the provided test/chain_test.go file for more detailed usage examples.
machine: Macbook Pro M1
memory: 8G
make benchmark
Output Results (Other Methods Are Supplemented):
$ make benchmark
cd test && go test -bench=. -benchmem -benchtime=1s -run=none
goos: darwin
goarch: arm64
pkg: github.com/here-Leslie-Lau/mongo-plus/test
BenchmarkFindOne-8 11989 96971 ns/op 6906 B/op 81 allocs/op
BenchmarkFind-8 13082 91575 ns/op 6449 B/op 81 allocs/op
BenchmarkInString-8 12154 98752 ns/op 6899 B/op 89 allocs/op
BenchmarkInInt64-8 12380 97217 ns/op 6517 B/op 81 allocs/op
BenchmarkSort-8 10000 101614 ns/op 6811 B/op 86 allocs/op
PASS
ok github.com/here-Leslie-Lau/mongo-plus/test 9.246s
When working or writing small pieces on my own, I often feel that using the official Go driver provided by MongoDB is somewhat inconvenient.
I've summarized personally, and there are several points as follows:
- When performing mongodb operations, you need to prepare various Option objects from the official driver and pass them all at once. Maybe it's the call chain approach of gorm that resonates with me 😄, so I also want to encapsulate it in a similar way.
- The official driver doesn't provide a very convenient way for pagination, (for example: getting the total page count/total number of items based on the page number/page size passed from the frontend or client), so each time it needs to be encapsulated again.
- I believe a library should try to shield the details as much as possible, and users shouldn't have to focus on the underlying implementation, making it ready to use. (For example, developers shouldn't need to understand BSON, various operators like $gt, sharding, etc.)
Options 1: Fork the repository, make your changes, and then initiate a "pull request" to submit your changes.
Options 2: Submit an Issue Directly
Status | Content |
---|---|
DONE | Basic MongoDB Operations (CRUD), User-Friendly Aggregation, Pagination Operations |
DONE | Add english documentation |
DONE | Support for MongoDB database management commands |
DONE | Monitor support |
DONE | Adding command-line tool support (creating indexes, etc.), use Cobra |
DONE | Logger option support |
DONE | Printing support for MongoDB native statements |
TODO | Transaction Support |
more and more...
Just give it a star~
Mongo-plus is licensed under the MIT License. See the LICENSE