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