golang mongo 查询总结
golang 使用 “gopkg.in/mgo.v2” 查询mongo总结。mongo的增加,更新和删除操作比较简单,查询操作相对灵活复杂一些,下面对golang 查询 mongo 做个总结。完整代码上传到了 https://gitee.com/truthalone/go-mongo.git 。
1.连接 mongo
//mongo.go package main import ( "errors" "time" "gopkg.in/mgo.v2" ) // 连接mongodb数据库 var ( mongodbAddr string = "" //mongodb数据库地址 mongodbName string = "" //mongodb数据名称 mongodbUser string = "" //mongodb用户名 mongodbPassword string = "" //mongodb密码 ) var ( session *mgo.Session ) func init() { mongodbAddr = "127.0.0.1" mongodbName = "demo" mongodbUser = "root" mongodbPassword = "ming" } func GetMongoSession() *mgo.Session { if session == nil { var err error if mongodbUser == "" || mongodbPassword == "" { session, err = mgo.Dial(mongodbAddr) } else { dialInfo := &mgo.DialInfo{ Addrs: []string{mongodbAddr}, Direct: false, Timeout: time.Second * 30, Database: mongodbName, Source: "admin", Username: mongodbUser, Password: mongodbPassword, PoolLimit: 4096, // Session.SetPoolLimit } session, err = mgo.DialWithInfo(dialInfo) } if err != nil { return nil } } return session.Clone() } func WithMongoCollection(collectionName string, s func(*mgo.Collection) error) error { session := GetMongoSession() if session == nil { return errors.New("获取mongodb连接失败") } defer session.Close() c := session.DB(mongodbName).C(collectionName) return s(c) }
2.插入数据
插入的数据包含子文档和数组数据,平时比较复杂的查询也是子文档查询和数组查询
//book.go //图书 type Book struct { Id bson.ObjectId `bson:"_id"` //主键 Name string `bson:"name"` //图书名称 Price float32 `bson:"price"` //价格 Authors []Author `bson:"author"` //作者 Tags []string `bson:"tags"` //标签 Press string `bson:"press"` //出版社 } //作者 type Author struct { Name string `bson:"name"` //姓名 Sex string `bson:"sex"` //性别 } const ( BookCollection = "book" ) func NewBook(name string, price float32, authors []Author, tags []string, press string) *Book { b := &Book{ Name: name, Price: price, Authors: authors, Tags: tags, Press: press, } b.Id = bson.NewObjectId() return b } func insert() { //声明为interface数组,才能批量插入 books := make([]interface{}, 0, 10) book1 := NewBook("高等数学上", 37.70, []Author{{"同济大学数学系", ""}}, []string{"数学", "大学数学", "高等数学"}, "高等教育出版社") books = append(books, book1) book2 := NewBook("TCP/IP详解卷1:协议", 45.00, []Author{{"W.Richard Stevens", "男"}, {"范建华", "男"}, {"胥光辉", "男"}, {"张涛", "男"}, {"谢希仁", "男"}}, []string{"计算机网络", "网络协议", "编程"}, "机械工业出版社") books = append(books, book2) book3 := NewBook("Python程序设计开发宝典", 69.00, []Author{{"董付国", "男"}}, []string{"程序设计", "编程", "python"}, "清华大学出版社") books = append(books, book3) book4 := NewBook("汇编语言", 36.00, []Author{{"王爽", ""}}, []string{"程序设计", "编程", "汇编"}, "清华大学出版社") books = append(books, book4) book5 := NewBook("SparkSQL入门与实践指南", 49.00, []Author{{"纪涵", "女"}, {"靖晓文", "女"}, {"赵政达", "男"}}, []string{"程序设计", "编程", "spark", "spark sql"}, "清华大学出版社") books = append(books, book5) expr1 := func(c *mgo.Collection) error { return c.Insert(books...) } err := WithMongoCollection(BookCollection, expr1) if err != nil { fmt.Println(err.Error()) return } fmt.Println("插入成功") }
3.定义查询输出
func searchAll(query bson.M) { var books []Book expr := func(c *mgo.Collection) error { return c.Find(query).All(&books) } err := WithMongoCollection(BookCollection, expr) if err != nil { fmt.Println(err.Error()) return } if len(books) == 0 { fmt.Println("未找到记录...") return } for _, book := range books { fmt.Println(book) } }
4.简单条件查询
//单个条件 = func equal() { query := bson.M{"name": "Python程序设计开发宝典"} searchAll(query) } //单个条件 > func gt() { query := bson.M{"price": bson.M{"$gt": 40.0}} searchAll(query) } //单个条件 < func lt() { query := bson.M{"price": bson.M{"$lt": 40.0}} searchAll(query) } //单个条件 >= func gte() { query := bson.M{"price": bson.M{"$gte": 45}} searchAll(query) } //单个条件 <= func lte() { query := bson.M{"price": bson.M{"$lte": 36}} searchAll(query) } //单个条件 != func ne() { query := bson.M{"press": bson.M{"$ne": "清华大学出版社"}} searchAll(query) }
5. 多合条件查询
// and //select * from table where price<=50 and press='清华大学出版社' func and() { query := bson.M{"price": bson.M{"$lte": 50}, "press": "清华大学出版社"} searchAll(query) } // or //select * from table where press='高等教育出版社' or press='清华大学出版社' func or() { query := bson.M{"$or": []bson.M{bson.M{"press": "高等教育出版社"}, bson.M{"name": "Python程序设计开发宝典"}}} searchAll(query) } // not // not条件只能用在正则表达式中 func not() { query := bson.M{"press": bson.M{"$not": bson.RegEx{Pattern: "^清华", Options: "i"}}} searchAll(query) } // 单个key的or查询可以使用 in 或 nin func in() { query := bson.M{"press": bson.M{"$in": []string{"清华大学出版社", "机械工业出版社"}}} searchAll(query) } func nin() { query := bson.M{"press": bson.M{"$nin": []string{"清华大学出版社", "机械工业出版社"}}} searchAll(query) }
6. 正则查询,字符串模糊查询
//正则查询 //$regex操作符的使用 // //$regex操作符中的option选项可以改变正则匹配的默认行为,它包括i, m, x以及s四个选项,其含义如下 // //i 忽略大小写,{<field>{$regex/pattern/i}},设置i选项后,模式中的字母会进行大小写不敏感匹配。 //m 多行匹配模式,{<field>{$regex/pattern/,$options:'m'},m选项会更改^和$元字符的默认行为,分别使用与行的开头和结尾匹配,而不是与输入字符串的开头和结尾匹配。 //x 忽略非转义的空白字符,{<field>:{$regex:/pattern/,$options:'m'},设置x选项后,正则表达式中的非转义的空白字符将被忽略,同时井号(#)被解释为注释的开头注,只能显式位于option选项中。 //s 单行匹配模式{<field>:{$regex:/pattern/,$options:'s'},设置s选项后,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符(\n),只能显式位于option选项中。 // //使用$regex操作符时,需要注意下面几个问题: // //i,m,x,s可以组合使用,例如:{name:{$regex:/j*k/,$options:"si"}} //在设置索引的字段上进行正则匹配可以提高查询速度,而且当正则表达式使用的是前缀表达式时,查询速度会进一步提高,例如:{name:{$regex: /^joe/} //字符串模糊查询 开头包含 func beginWith() { query := bson.M{"name": bson.M{"$regex": bson.RegEx{Pattern: "^高等", Options: "i"}}} searchAll(query) } //模糊查询 包含 func contains() { //query := bson.M{"name": bson.M{"$regex": "开发", "$options": "$i"}} query := bson.M{"name": bson.M{"$regex": bson.RegEx{Pattern: "开发", Options: "i"}}} searchAll(query) } //模糊查询 结尾包含 func endWith() { query := bson.M{"name": bson.M{"$regex": bson.RegEx{Pattern: "指南$", Options: "i"}}} searchAll(query) }
7.数组查询
//数组查询,数组中的元素可能是单个值数据,也可能是子文档 //针对单个值数据 //满足数组中单个值 func arrayMatchSingle() { query := bson.M{"tags": "编程"} searchAll(query) } //同时满足所有条件,不要求顺序 func arrayMatchAll() { query := bson.M{"tags": bson.M{"$all": []string{"程序设计", "编程", "python"}}} searchAll(query) } //查询特定长度 func arrayMatchSize() { query := bson.M{"tags": bson.M{"$size": 4}} searchAll(query) } //满足特定索引下条件 //数组索引从0开始,我们匹配第二项就用tags.1作为键 func arrayMatchIndex() { query := bson.M{"tags.1": "编程"} searchAll(query) } //精确查找,数量,顺序都要满足 func arrayMatch() { query := bson.M{"tags": []string{"数学", "大学数学", "高等数学"}} searchAll(query) } //针对与数组中的子文档 //满足单个价值 func subDocMatchSingle() { query := bson.M{"author.name": "纪涵"} searchAll(query) } //elementMath func subDocMatchElement() { query := bson.M{"author": bson.M{"$elemMatch": bson.M{"name": "谢希仁", "sex": "男"}}} searchAll(query) }
8.聚合管道查询
//记数 func count() { var count int expr := func(c *mgo.Collection) error { var err error count, err = c.Find(bson.M{}).Count() return err } err := WithMongoCollection(BookCollection, expr) if err != nil { fmt.Println(err.Error()) return } fmt.Println(count) } //去重 func distinct() { var result []interface{} expr := func(c *mgo.Collection) error { return c.Find(bson.M{}).Distinct("press", &result) } err := WithMongoCollection(BookCollection, expr) if err != nil { fmt.Println(err.Error()) return } fmt.Println(result) } //求和 //golang mongo 管道查询中,可以先使用"$match"过滤出复合条件的数据, //然后使用"$project"投射出想要的结果字段,然后使用 "$group" 进行分组聚合。 //"$group" 根据 "_id"来分组,可以通过多个字段来定义 "_id"来进行分组。 func sum() { query := []bson.M{ //bson.M{"$match": bson.M{"press": "清华大学出版社"}}, bson.M{"$project": bson.M{"_id": 0, "price": 1, "press": 1}}, bson.M{"$group": bson.M{"_id": "$press", "totalPrice": bson.M{"$sum": "$price"}}}, } var result []bson.M expr := func(c *mgo.Collection) error { return c.Pipe(query).All(&result) } err := WithMongoCollection(BookCollection, expr) if err != nil { fmt.Println(err.Error()) return } fmt.Println(result) } //最大值和最小值 func maxAndMin() { query := []bson.M{ bson.M{"$group": bson.M{"_id": nil,"maxPrice": bson.M{"$max": "$price"},"minPrice":bson.M{"$min":"$price"}}}, } var result []bson.M expr := func(c *mgo.Collection) error { return c.Pipe(query).All(&result) } err := WithMongoCollection(BookCollection, expr) if err != nil { fmt.Println(err.Error()) return } fmt.Println(result) } //平均值 func avg(){ query := []bson.M{ bson.M{"$group": bson.M{"_id": nil,"avgPrice": bson.M{"$avg": "$price"}}}, } var result []bson.M expr := func(c *mgo.Collection) error { return c.Pipe(query).All(&result) } err := WithMongoCollection(BookCollection, expr) if err != nil { fmt.Println(err.Error()) return } fmt.Println(result) }
https://blog.csdn.net/tianwenxue/article/details/106316255