go get github.com/qiniu/qmgo
import (
"context"
"errors"
"fmt"
"github.com/qiniu/qmgo"
"github.com/qiniu/qmgo/options"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/event"
mgoptions "go.mongodb.org/mongo-driver/mongo/options"
"gorm.io/gorm"
"log"
"strings"
"sync"
"time"
)
const (
Ip = "127.0.0.1"
Port = "27017"
UserName = "test"
Password = "123456789"
DBName = "test"
AuthSource = "test"
)
var(
ConnectTimeoutMS = int64(1000)
MaxPoolSize = uint64(100)
MinPoolSize = uint64(0)
)
ctx := context.Background()
// 拼接MongoDB Url
var mongoUrl string
if Password != "" {
mongoUrl = "mongodb://" + UserName + ":" + Password + "@" +
Ip + ":" + Port + "/" + DBName +
"?authSource=" + AuthSource
} else {
mongoUrl = "mongodb://" + Ip + ":" + Port
}
// 创建cmdMonitor,用于打印SQL
//startedCommands := make(map[int64]bson.Raw)
startedCommands := sync.Map{} // map[int64]bson.Raw
cmdMonitor := &event.CommandMonitor{
Started: func(_ context.Context, evt *event.CommandStartedEvent) {
startedCommands.Store(evt.RequestID, evt.Command)
//startedCommands[evt.RequestID] = evt.Command
},
Succeeded: func(_ context.Context, evt *event.CommandSucceededEvent) {
//log.Printf("Command: %v Reply: %v\n",
// startedCommands[evt.RequestID],
// evt.Reply,
//)
var commands bson.Raw
v, ok := startedCommands.Load(evt.RequestID)
if ok {
commands = v.(bson.Raw)
}
log.Printf("\n【MongoDB】[%.3fms] [%v] %v \n", float64(evt.DurationNanos)/1e6, commands, evt.Reply)
},
Failed: func(_ context.Context, evt *event.CommandFailedEvent) {
//log.Printf("Command: %v Failure: %v\n",
// startedCommands[evt.RequestID],
// evt.Failure,
//)
var commands bson.Raw
v, ok := startedCommands.Load(evt.RequestID)
if ok {
commands = v.(bson.Raw)
}
log.Printf("\n【MongoDB】[%.3fms] [%v] \n %v \n", float64(evt.DurationNanos)/1e6, commands, evt.Failure)
},
}
// 创建options
ops := options.ClientOptions{ClientOptions: &mgoptions.ClientOptions{}}
ops.SetMonitor(cmdMonitor)
// 创建一个数据库链接
client, err := qmgo.NewClient(ctx, &qmgo.Config{
Uri: mongoUrl,
ConnectTimeoutMS: &ConnectTimeoutMS,
MaxPoolSize: &MaxPoolSize,
MinPoolSize: &MinPoolSize,
}, ops)
if err != nil {
err = errors.New("MongoDB连接异常:" + err.Error())
return
}
// 选择数据库
db := client.Database(DBName)
// 在初始化成功后,请defer来关闭连接
defer func() {
if err = client.Close(ctx); err != nil {
panic(err)
}
}()
// 选择数据库
db := client.Database("dbname")
// 选中集合
coll := db.Collection("user1")
// 创建集合
err = db.CreateCollection(ctx, "coll1")
// 删除集合
err = coll.DropCollection(ctx)
// 定义用于接收数据的结构体
type ListCollections struct {
Cursor struct {
FirstBatch []struct {
Name string `json:"name"`
} `json:"firstBatch"`
} `json:"cursor"`
}
// 使用Command获取集合列表
result := db.RunCommand(ctx, bson.D{{"listCollections", 1}})
if result.Err() != nil {
err = result.Err()
return
}
var listColl ListCollections
// 将数据反序列化
err = result.Decode(&listColl)
if err != nil {
return
}
// 遍历打印
for _, batch := range listColl.Cursor.FirstBatch {
fmt.Println(batch.Name)
}
type UserInfo struct {
Name string `bson:"name"`
Age uint16 `bson:"age"`
Weight uint32 `bson:"weight"`
ExpireDate time.Time `bson:"expire_date"` // TTL索引对应的字段必须是date类型
}
插入一条
// 插入一个文档
result, err := coll.InsertOne(ctx, userInfo)
if err != nil {
log.Fatalln(err)
}
fmt.Println(result.InsertedID)
插入多条
// 创建数据
var userInfos = []UserInfo{
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 := coll.InsertMany(ctx, userInfos)
if err != nil {
log.Fatalln(err)
}
fmt.Println(result.InsertedIDs)
更新一条
// 查询条件
filter := bson.M{
"name": "d4",
}
// 更新字段
update := bson.M{
"$set": bson.M{"age": 7},
}
// 更新一条
err = coll.UpdateOne(ctx, filter, update)
更新多条
// 查询条件
filter := bson.M{
"name": "d4",
}
// 更新字段
update := bson.M{
"$set": bson.M{"age": 7},
}
// 更新多条
result,err := coll.UpdateAll(ctx, filter, update)
删除字段
// 查询条件
filter := bson.M{
"name": "d4",
}
// 删除字段字段
update := bson.M{
"$unset": bson.M{"age": ""},
}
// 更新多条
result,err := coll.UpdateAll(ctx, filter, update)
删除一条
// 查询条件
filter := bson.M{
"name": "a1",
}
// 删除一条
err = coll.Remove(ctx, filter)
会查询到匹配数据会报如下异常:
panic: mongo: no documents in result
删除多条
// 查询条件
filter := bson.M{
"name": "a1",
}
// 删除多条
_,err = coll.RemoveAll(ctx, filter)
查询一条
// 一定要初始化,否则报错,网上很多文章都没有做这一步
var findOptions = &options.FindOptions{}
// 查询一个文档
one := UserInfo{}
err = coll.Find(ctx, findOptions).One(&one)
查询多条
// 一定要初始化,否则报错,网上很多文章都没有做这一步
var findOptions = &options.FindOptions{}
// 查询所有文档
var users []UserInfo
err = coll.Find(ctx, findOptions).All(&users)
分页查询
// 页码
page := int64(1)
// 每页大小
pageSize := int64(10)
// 查询数据
err = coll.Find(ctx, findOptions).Skip((page-1) * pageSize).Limit(pageSize).All(users)
排序
// 正序
err = coll.Find(ctx, findOptions).Sort("weight").All(&users)
// 逆序
err = coll.Find(ctx, findOptions).Sort("-weight").All(&users)
// 组合排序
err = coll.Find(ctx, findOptions).Sort("age","-weight").All(&users)
Count
// 统计数据总量
count, err = db.Find(ctx, findOptions).Count()
OR
// 查询条件
filter := bson.M{
"$or": bson.A{
bson.M{"age": 5},
bson.M{"age": 6},
bson.M{"age": 7},
},
}
// 查询所有数据
err = coll.Find(ctx, filter).All(&ones)
IN
// 查询条件
filter := bson.M{
"age": bson.M{
"$in": bson.A{5, 6, 7},
},
}
// 查询所有数据
err = coll.Find(ctx, filter).All(&ones)
NOT IN
// 查询条件
filter := bson.M{
"age": bson.M{
"$nin": bson.A{5, 6, 7},
},
}
// 查询所有数据
err = coll.Find(ctx, filter).All(&ones)
大于,大于等于,小于,小于等于,不等于
// 查询条件
filter := bson.M{
"age": bson.M{
"$gt": 5, // 大于
"$gte": 5, // 大于等于
"$lt": 10, // 小于
"$lte": 10, // 小于等于
"$ne": 5, // 不等于
},
}
// 查询所有数据
err = coll.Find(ctx, filter).All(&ones)
LIKE
// 需要模糊查询的内容
value := "xm"
// 查询条件
filter := bson.M{
"name": primitive.Regex{
Pattern: value,
Options: "",
},
}
// 查询所有数据
err = coll.Find(ctx, filter).All(&ones)
DISTINCT
var names []string
// 查询条件
var findOptions = &options.FindOptions{}
// DISTINCT
err = coll.Find(ctx, findOptions).Distinct("name", &names)
GROUP
// 查询结果
var showsWithInfo []bson.M
// 过滤条件
matchStage := bson.D{{
"$match", []bson.E{
{
"age", bson.D{{"$gt", 5}, {"$lte", 6}}, // 5 < age <= 6
},
{
"name", "a1", // name = a1
},
},
}}
// 分组条件
groupStage := bson.D{{
"$group", bson.D{
{
"_id", bson.D{
{"name", "$name"}, // 对name字段进行分组查询
{"age", "$age"}, // 对age字段进行分组查询
},
},
{
"age_sum", bson.D{{"$sum", "$age"}}, // 计算总和
},
{
"age_max", bson.D{{"$max", "$age"}}, // 计算最大值
},
{
"age_min", bson.D{{"$min", "$age"}}, // 计算最小值
},
{
"age_avg", bson.D{{"$avg", "$age"}}, // 计算平均值
},
},
}}
// 查询
err = coll.Aggregate(context.Background(), mongo.Pipeline{matchStage, groupStage}).All(&showsWithInfo)
指定x秒后过期
"github.com/qiniu/qmgo/options"
mgoptions "go.mongodb.org/mongo-driver/mongo/options"
// TTL索引
indexModel := options.IndexModel{
Key: []string{"expire_date"},
IndexOptions: mgoptions.Index().SetExpireAfterSeconds(3600),
}
coll.CreateOneIndex(ctx, indexModel)
指定到具体的时间节点过期
"github.com/qiniu/qmgo/options"
mgoptions "go.mongodb.org/mongo-driver/mongo/options"
// TTL索引
indexModel := options.IndexModel{
Key: []string{"expire_date"},
IndexOptions: mgoptions.Index().SetExpireAfterSeconds(0),
}
coll.CreateOneIndex(ctx, indexModel)