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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM