代码例子在最下面,不看介绍直接下滑
以下所有例子中结构定义如下:
type User struct {
Id_ bson.ObjectId `bson:"_id"`
Name string `bson:"name"`
Age int `bson:"age"`
JoinedAt time.Time `bson:"joined_at"`
Interests []string `bson:"interests"
}
1、查询
通过func (c *Collection) Find(query interface{}) *Query来进行查询,返回的Query struct可以有附加各种条件来进行过滤。
通过Query.All()可以获得所有结果,通过Query.One()可以获得一个结果,注意如果没有数据或者数量超过一个,One()会报错。
条件用bson.M{key: value},注意key必须用MongoDB中的字段名,而不是struct的字段名。
1.1、连接并查询(下面所有集合用c代替)
ctx, canf := context.WithTimeout(context.Background(), 10*time.Second)
// defer canf()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(driver))
if err != nil {
return nil, err
}
c:= client.Database(database).Collection(collect)
c.Find(ctx, where, opts...)
上面代码可以把所有Users都查出来:
1.2、根据ObjectId查询,单条语句
c.FindOne(m.Ctx, where, opts...).Decode(&result)
注意这里没有处理err。注意自己的查询ERR。
关键是这个
关键是这个
关键是这个
1.3、单条件查询
等于($eq)
c.Find(bson.M{"name": "Jimmy Kuu"})
不等于($ne)
c.Find(bson.M{"name": bson.M{"$ne": "Jimmy Kuu"}})
大于($gt)
c.Find(bson.M{"age": bson.M{"$gt": 32}})
小于($lt)
c.Find(bson.M{"age": bson.M{"$lt": 32}})
大于等于($gte)
c.Find(bson.M{"age": bson.M{"$gte": 33}})
小于等于($lte)
c.Find(bson.M{"age": bson.M{"$lte": 31}})
in($in)
c.Find(bson.M{"name": bson.M{"$in": []string{"Jimmy Kuu", "Tracy Yu"}}})
no in($nin)
同$in,
是否包含这个键($exists)
c.Find(bson.M{"name": bson.M{"$exists": true}})
查询键值为null的字段
c.Find(bson.M{"name": bson.M{"$in":[]interface{}{null}, "$exists": true}})
模糊查询($regex)
c.Find(bson.M{"name": bson.M{"$regex": "^[0-9]+"}})
c.Find(bson.M{"name": bson.M{"$regex": primitive.Regex{Pattern: "[aa]+", Options: "im"}}})//查出包含aa的,后面的是正则表达式
$size
查询键值为长度是size的数组
c.Find(bson.M{"Interests": bson.M{"$size": 3}})
上面就是查询Interests数组长度为3的所有人
$all
查询数组中包含所有值得匹配(不分顺序,只看包含与否)
c.Find(bson.M{"Interests": bson.M{"$all": []string{"11","22","33"}}})
上面就是查询Interests中包含11,22,33的所有人
如果数组只有一项内容
c.Find(bson.M{"Interests": bson.M{"$all": []string{"11"}}})
c.Find(bson.M{"Interests": "11"})
以上结果一致
key.index
如果要查询数组指定位置
c.Find(bson.M{"Interests.2": "33"})
以上就是查询Interests的第二个元素为"33"的所有人
1.4、多条件查询
and($and)
c.Find(bson.M{"name": "Jimmy Kuu", "age": 33})
or($or)
c.Find(bson.M{"$or": []bson.M{bson.M{"name": "Jimmy Kuu"}, bson.M{"age": 31}}})
2、修改
通过func (*Collection) Update来进行修改操作。
func (c *Collection) Update(selector interface{}, change interface{}) error
注意修改单个或多个字段需要通过$set操作符号,否则集合会被替换。
2.1、($set)
修改字段的值
c.Update(
bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
bson.M{"$set": bson.M{ "name": "Jimmy Gu", "age": 34, }}
)
2.2、inc($inc)
字段增加值
c.Update(
bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
bson.M{"$inc": bson.M{ "age": -1, }}
)
2.3、push($push)
从数组中增加一个元素
c.Update(
bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
bson.M{"$push": bson.M{ "interests": "Golang", }}
)
2.4、pull($pull)
从数组中删除一个元素
c.Update(
bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
bson.M{"$pull": bson.M{ "interests": "Golang", }}
)
2.5、删除
c.Remove(bson.M{"name": "Jimmy Kuu"})
这里也支持多条件,参考多条件查询。
例子一
package main
import (
"context"
"log"
"go.mongodb.org/mongo-driver/mongo/readpref"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"gopkg.in/mgo.v2/bson"
)
func main() {
ctx, canf := context.WithCancel(context.Background())
defer canf()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Println("err:", err)
return
}
if err := client.Ping(ctx, readpref.Primary()); err != nil {
log.Println("err:", err)
return
}
clo := client.Database("stb")
// insert(ctx, clo)
// update(ctx, clo)
delete(ctx, clo)
selectOne(ctx, clo)
}
func insert(ctx context.Context, db *mongo.Database) {
data := bson.M{"room_id": "123", "host_name": "shitingbao", "room_name": "mantou", "room_type": "love", "common": "loss"}
_, err := db.Collection("chatroom").InsertOne(ctx, data)
if err != nil {
log.Println("err:", err)
return
}
}
func update(ctx context.Context, db *mongo.Database) {
_, err := db.Collection("chatroom").UpdateOne(ctx, bson.M{"room_id": "123"}, bson.M{"$set": bson.M{"host_name": "mantou"}})
if err != nil {
log.Println("err:", err)
return
}
}
func delete(ctx context.Context, db *mongo.Database) {
if err := db.Collection("chatroom").FindOneAndDelete(ctx, bson.M{"room_id": "123"}).Err(); err != nil {
log.Println("err:", err)
return
}
}
func selectOne(ctx context.Context, db *mongo.Database) {
var result bson.M
if err := db.Collection("chatroom").FindOne(ctx, bson.M{"room_id": "123"}).Decode(&result); err != nil {
log.Println("err:", err)
return
}
log.Println(result)
}
例子二,带函数使用的例子(limit,skip等)
这里注意的是,https://github.com/mongodb/mongo-go-driver 中没有直接使用的该方法,因为他已经从中间剥离出来了,在该包下面的options包下面重新定义一个结构,进行设置,或者调用对应方法操作。
一下面例子为例,Find方法反馈一个FindOptions结构体,可以从源码中了解到,所有的属性都有,当然你可以自己定义一个,不过这个类型转化太麻烦,就直接使用他包装好的函数,比如这里设置跳过数据的skip函数,跳过两条数据,其他的函数同理使用。
//查询name为aa的第三条数据开始的数据
func selectWhere(ctx context.Context, db *mongo.Database) {
var result []bson.M
cur, err := db.Collection("collect").Find(ctx, bson.M{"name":"aa"}, options.Find().SetSkip(2))
if err != nil {
return
}
defer cur.Close(ctx)
for cur.Next(ctx) {
var res bson.M
if err := cur.Decode(&res); err != nil {
return
}
result = append(result, res)
}
if err := cur.Err(); err != nil {
return
}
log.Println(result)
}
聚合函数,注意pipeline 内容,其他都不重要
func OpenMongoDb(client *mongo.Client, driver, database,collection string) error {
ctx := context.TODO()
clo := client.Database(database).Collection(collection )
pipeline := []bson.M{//注意这个,这是个数组,对应就行
{
//第一位必须要是累加器对象,就是这个id,对应你要聚合的实际列名,这里是name
//第二位是列的名称count,自己取一个名字类似于sql中as后面的名称,里面那个是固定格式
//对应的sql就是,select name,sum(name) as count from table group by name
"$group": bson.M{"_id": "$name", "count": bson.M{"$sum": 1}},
},
}
cur, err := clo.Aggregate(ctx, pipeline)
if err != nil {
return err
}
var result []bson.M
defer cur.Close(ctx)
for cur.Next(ctx) {
var res bson.M
if err := cur.Decode(&res); err != nil {
return err
}
result = append(result, res)
}
if err := cur.Err(); err != nil {
return err
}
log.Println(result)
return nil
}
上述的聚合,对于多列就是,相当于group by name,age
pipeline := []bson.M{
{
"$group": bson.M{"_id": bson.M{"name": "$name", "age": "$age"}, "count": bson.M{"$sum": 1}},
},
}
//对应mongodb语句就是
db.chatroom.aggregate([{$group:{_id:{"name":"$name","age":"$age"},num_tutorial:{$sum:1}}}])
再举个例子
db.chatroom.aggregate([{$match:{name:{$nin:["aa","bb"]}}},{$sample:{size:3}}])
对应的就是
where := []bson.M{
{
"$match": bson.M{
"name": bson.M{
"$nin": pm.RoomID},
},
},
{
"$sample": bson.M{
"size": 3,
},
},
}
cur, err := core.Mdb.CollectionDB.Collection("chatroom").Aggregate(core.Mdb.Ctx, where)
if err != nil {
return err
}
var result []bson.M
defer cur.Close(core.Mdb.Ctx)
for cur.Next(core.Mdb.Ctx) {
var res bson.M
if err := cur.Decode(&res); err != nil {
return err
}
result = append(result, res)
}
if err := cur.Err(); err != nil {
return err
}
log.Println(result)