Qmgo
is a MongoDB
driver
for Go
. It is based on MongoDB official driver, but easier to use like mgo (such as the chain call).
-
Qmgo
can allow user to use the new features ofMongoDB
in a more elegant way. -
Qmgo
is the first choice for migrating frommgo
to the newMongoDB driver
with minimal code changes.
-Go 1.10
and above.
-MongoDB 2.6
and above.
- CRUD to documents
- Configuration when create connection:connection pool、pool Monitor、Auth、ReadPreference
- Create indexes
- Sort、limit、count、select
- Cursor
- Aggregate
- Transactions
The recommended way is to use go mod
to automatically install dependencies by import github.com/qiniu/qmgo
and build
.
Of course, the following methods are also feasible:
go get github.com/qiniu/qmgo
- Start
import
and create a new connection
import (
"context"
"github.com/qiniu/qmgo"
)
ctx := context.Background()
client, err := qmgo.NewClient(ctx, &qmgo.Config{Uri: "mongodb://localhost:27017"})
db := client.Database("class")
coll := db.Collection("user")
If your connection points to a fixed database and collection, we recommend using the following more convenient way to initialize the connection.
All operations are based on cli
and no longer need to care about the database and collection.
cli, err := qmgo.Open(ctx, &qmgo.Config{Uri: "mongodb://localhost:27017", Database: "class", Coll: "user"})
The following examples will be based on cli
, if you use the first way for initialization, replace cli
with client
、db
or coll
After the initialization is successful, please defer
to close the connection
defer func() {
if err = cli.Close(ctx); err != nil {
panic(err)
}
}()
- Create index
Before doing the operation, we first initialize some data:
type UserInfo struct {
Name string `bson:"name"`
Age uint16 `bson:"age"`
Weight uint32 `bson:"weight"`
}
var oneUserInfo = UserInfo{
Name: "xm",
Age: 7,
Weight: 40,
}
Create index
cli.EnsureIndexes(ctx, []string{}, []string{"age", "name,weight"})
- Insert a document
// insert one document
result, err := cli.Insert(ctx, oneUserInfo)
- Find a document
// find one document
one := UserInfo{}
err = cli.Find(ctx, bson.M{"name": oneUserInfo.Name}).One(&one)
- Delete documents
err = cli.Remove(ctx, bson.M{"age": 7})
- Insert multiple data
// multiple insert
var batchUserInfoI = []interface{}{
UserInfo{Name: "a1", Age: 6, Weight: 20},
UserInfo{Name: "b2", Age: 6, Weight: 25},
UserInfo{Name: "c3", Age: 6, Weight: 30},
UserInfo{Name: "d4", Age: 6, Weight: 35},
UserInfo{Name: "a1", Age: 7, Weight: 40},
UserInfo{Name: "a1", Age: 8, Weight: 45},
}
result, err = cli.Collection.InsertMany(ctx, batchUserInfoI)
- Search all, sort and limit
// find all, sort and limit
batch := []UserInfo{}
cli.Find(ctx, bson.M{"age": 6}).Sort("weight").Limit(7).All(&batch)
- Count
count, err := cli.Find(ctx, bson.M{"age": 6}).Count()
- Update
// UpdateOne one
err := cli.UpdateOne(ctx, bson.M{"name": "d4"}, bson.M{"$set": bson.M{"age": 7}})
// UpdateAll
result, err := cli.UpdateAll(ctx, bson.M{"age": 6}, bson.M{"$set": bson.M{"age": 10}})
- Select
err := cli.Find(ctx, bson.M{"age": 10}).Select(bson.M{"age": 1}).One(&one)
- Aggregate
matchStage := bson.D{{"$match", []bson.E{{"weight", bson.D{{"$gt", 30}}}}}}
groupStage := bson.D{{"$group", bson.D{{"_id", "$name"}, {"total", bson.D{{"$sum", "$age"}}}}}}
var showsWithInfo []bson.M
err = cli.Aggregate(context.Background(), Pipeline{matchStage, groupStage}).All(&showsWithInfo)
- Pool Monitor
poolMonitor := &event.PoolMonitor{
Event: func(evt *event.PoolEvent) {
switch evt.Type {
case event.GetSucceeded:
fmt.Println("GetSucceeded")
case event.ConnectionReturned:
fmt.Println("ConnectionReturned")
}
},
}
cli, err := Open(ctx, &Config{Uri: URI, Database: DATABASE, Coll: COLL, PoolMonitor: poolMonitor})
- Transactions
The super simple and powerful transaction, with features like timeout
、retry
:
callback := func(sessCtx context.Context) (interface{}, error) {
// Important: make sure the sessCtx used in every operation in the whole transaction
if _, err := cli.InsertOne(sessCtx, bson.D{{"abc", int32(1)}}); err != nil {
return nil, err
}
if _, err := cli.InsertOne(sessCtx, bson.D{{"xyz", int32(999)}}); err != nil {
return nil, err
}
return nil, nil
}
result, err = cli.DoTransaction(ctx, callback)
Below we give an example of multi-file search、sort and limit to illustrate the similarities between qmgo
and mgo
and the improvement compare to go.mongodb.org/mongo-driver
.
How do we do ingo.mongodb.org/mongo-driver
:
// go.mongodb.org/mongo-driver
// find all, sort and limit
findOptions := options.Find()
findOptions.SetLimit(7) // set limit
var sorts D
sorts = append(sorts, E{Key: "weight", Value: 1})
findOptions.SetSort(sorts) // set sort
batch := []UserInfo{}
cur, err := coll.Find(ctx, bson.M{"age": 6}, findOptions)
cur.All(ctx, &batch)
How do we do in Qmgo
and mgo
:
// qmgo
// find all, sort and limit
batch := []UserInfo{}
cli.Find(ctx, bson.M{"age": 6}).Sort("weight").Limit(7).All(&batch)
// mgo
// find all, sort and limit
coll.Find(bson.M{"age": 6}).Sort("weight").Limit(7).All(&batch)
Differences between qmgo and mgo
If you are using qmgo, please feel free to add your project name or repository here!
- Qiniu QCDN management system
- Qiniu RTC quality monitoring system
- Jesselivermore huanshoulv stock real-time quotes system
The Qmgo project welcomes all contributors. We appreciate your help!