golang mgo 库的简单使用备忘
2020-11-01 tech go 15 mins 5502 字
最近 golang 开发用到 mongodb,由于一些原因,我使用了 mgo 包进行开发。这篇文章记录一下 mgo 包的用法,一个比较浅的记录,做个备忘。
目前 mgo 已经不维护了,类似的包还有 官方 和七牛 (七牛的包基于mongo官方)的,都不错,可以试试。
mgo 的使用例子推荐这个网站——learningprogramming.net,写的挺好。
安装
go get gopkg.in/mgo.v2
使用
连接服务器
var mgoSession *mgo.Session
var mgoDatabase *mgo.Database
func GetMgo() *mgo.Session {
return mgoSession
}
func GetDataBase() *mgo.Database {
sessionCopy := mgoSession.Copy()
mgoDatabase = sessionCopy.DB(setting.Config.Mongo.Database)
return mgoDatabase
}
type Config struct {
URL string
Database string
Collection string
ReplicaSet string
}
func Setup(){
mgoSession, err := mgo.Dial("username:password@10.19.0.57:7018,10.19.0.58:7018/dbname?replicaSet=replsetname")
if err != nil {
logrus.Error(err)
}
mgoSession.SetMode(mgo.Monotonic, true)
mgo.SetDebug(true)
}
// 创建索引
func EnsureIndex(col string,keyArray []string) {
mongoCol := GetDataBase().C(col)
for _, key := range keyArray {
err := mongoCol.EnsureIndex(
mgo.Index{
Key: []string{key},
Background: true,
})
if err != nil {
logrus.Errorln("create index error: ", err)
}
}
}
切换db
db := session.DB("test")
切换collection
c := db.C("users")
这样就能对mongo进行操作啦。
查找
查询可以用find,也可以用聚合管道(Aggregation Pipeline)。
find 就是普通的查询,聚合管道可以对集合中的文档进行变换和组合。
聚合管道以一个集合中的所有文档作为开始,然后这些文档从一个操作节点流向下一个节点 ,每个操作节点对文档做相应的操作。这些操作可能会创建新的文档或者过滤掉一些不符合条件的文档,在管道中可以对文档进行重复操作。
find
m := bson.M{
"CurTimestamp": bson.M{
"$gte": start,
"$lte": end,
},
"Account": account,
"ToNodeType": "cloud",
}
c.Find(m).Count()
pipeline
import "gopkg.in/mgo.v2/bson"
match := bson.M{}
if len(receivedData.Method) > 0 {
matchIn := []interface{}{}
for _, v := range receivedData.Method {
matchIn = append(matchIn, v)
}
match["RequestMethod"] = bson.M{"$in":matchIn}
}
match["time"] = bson.M{"$lt": endedAt,"$gt": startedAt}
pipeline := []bson.M{
{"$match": match},
{"$sort": bson.M{"time": -1}},
{"$limit": limit},
{"$skip": skip},
}
var xxxList []xxxItem
c.Pipe(pipeline).All(&xxxList)
mapreduce
目前还没有使用mapreduce,以下例子来自《谈谈一些关于mgo的用法》
m := new(mgo.MapReduce)
m.Map = `function() { var date = new Date();
date.setTime(this.CurTimestamp / 1000);
var hour = date.getHours();
if((hour >= 6) && (hour <= 11)) {
result.morning++;
}else if((hour >= 12) && (hour <= 18)){
result.afternoon ++;
}else if((hour >= 19) && (hour <= 23)) {
result.night ++;
}else{
result.am ++;
}
emit(this.Account, {});}`
m.Reduce = `function() {return result;}`
m.Scope = bson.M{
"result": bson.M{
"morning": 0,
"afternoon": 0,
"night": 0,
"am": 0,
},
}
var value []timeResult
c.Find().MapReduce(m, &value)
update
import "gopkg.in/mgo.v2/bson"
err = c.UpdateId(bson.ObjectIdHex(xxx.ID.Hex()), bson.M{"$set": bson.M{"ClientUsername": username,}})
err := c.Update(bson.M{"wsid": wsid}, bson.M{"$set": bson.M{"endtime": time.Now(),}})
修改字段的值($set)
c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, bson.M{"$set": bson.M{ "name": "Jimmy Gu", "age": 34, }})
字段增加值inc($inc)
c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, bson.M{"$inc": bson.M{ "age": -1, }})
从数组中增加一个元素push($push)
c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, bson.M{"$push": bson.M{ "interests": "Golang", }})
从数组中删除一个元素pull($pull)
c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, bson.M{"$pull": bson.M{ "interests": "Golang", }})
create
create := XxxStruct{}
create.Time = time.Now()
create.Wsid = wsid
c.Insert(create)
remove
c.Remove(bson.M{"name": "Jimmy Kuu"})
条件匹配
=($eq)
c.Find(bson.M{"name": "Jimmy Kuu"}).All(&users)
!=($ne)
c.Find(bson.M{"name": bson.M{"$ne": "Jimmy Kuu"}}).All(&users)
>($gt)
c.Find(bson.M{"age": bson.M{"$gt": 32}}).All(&users)
<($lt)
c.Find(bson.M{"age": bson.M{"$lt": 32}}).All(&users)
>=($gte)
c.Find(bson.M{"age": bson.M{"$gte": 33}}).All(&users)
<=($lte)
c.Find(bson.M{"age": bson.M{"$lte": 31}}).All(&users)
in($in)
c.Find(bson.M{"name": bson.M{"$in": []string{"Jimmy Kuu", "Tracy Yu"}}}).All(&users)
$nin 不在集合内
iter = c.Find(bson.M{"city": bson.M{"$nin": []string{"Shanghai", "Hangzhou"}}}).Iter()
$exists 是否包含键
iter = c.Find(bson.M{"city": bson.M{"$exists": true}}).Iter()
键值为null(键存在,键值为null)
iter = c.Find(bson.M{"city": bson.M{"$in": []interface{}{nil}, "$exists": true}}).Iter()
and($and)
c.Find(bson.M{"name": "Jimmy Kuu", "age": 33}).All(&users)
or($or)
c.Find(bson.M{"$or": []bson.M{bson.M{"name": "Jimmy Kuu"}, bson.M{"age": 31}}}).All(&users)
结果操作
排序 Sort
//按age升序,如果要降序Sort("-age")
iter = c.Find(bson.M{"age": bson.M{"$gte": 33}}).Sort("age").Iter()
限定结果数量 Limit
//使用Limit限定只去5条记录
iter = c.Find(bson.M{"age": bson.M{"$gte": 20}}).Sort("age").Limit(5).Iter()
跳过指定数量的记录 Skip
//跳过两条记录,取接下来的5条记录
iter = c.Find(bson.M{"age": bson.M{"$gte": 20}}).Sort("age").Skip(2).Limit(5).Iter()
计算记录的条数 Count
recordsCount, err := c.Find(bson.M{"age": bson.M{"$gte": 20}}).Count()
参考资料
- https://gopkg.in/mgo.v2
- go+aggregate实时聚合mongo千万文档数据
- Go 的 MogonDB 包 mgo 使用
- mongodb在golang的应用
- 谈谈一些关于mgo的用法
- labix.org/mgo 连接池泄漏问题
- golang mgo的mongo连接池设置:必须手动加上maxPoolSize
- Golang 的 mgo 连接池
- mgo 的 session 与连接池
- 一日一学_Go语言mgo(mongo场景应用)
- 关于mongodb:如何使用$ group聚合计算数据内部记录的总数
- mgo和mongo-go-driver使用心得比较
- golang mgo使用
- 我可以使用golang(mgo)在一个查询中聚合两个mongodb查询吗?
- Go中的MongoDB聚合查找(mgo.v2)
- Golang MGO Group按多个参数分组并按日期时间获取最后一个
- go中mgo操作数据库的一些示例
- mongodb查询案例,golang库mgo案例