Go語言實踐篇之MongoDB

Go語言中MongoDB的使用

關於MongoDB數據的基本介紹與環境搭建相關知識,可參見我的另一篇文章 文檔數據庫 MongoDB

環境準備

mgo簡介
mgo(音mango)是MongoDB的Go語言驅動,它用基於Go語法的簡單API實現了豐富的特性,並經過良好測試。
官方網站:http://labix.org/mgo

API文檔

安裝

go get gopkg.in/mgo.v2

快速上手

mgo簡單操作步驟

  1. 導入mgo包
  2. 連接MongoDB服務
  3. 打開指定的數據庫,獲得一個Database對象(不存在則創建)
  4. 打開指定的集合,獲得一個Collection對象(不存在則創建)
  5. 調用Collection對象的方法進行CRUD操作

以下創建一個名爲test數據庫,並創建一個名爲people的集合

package main

import (
        "fmt"
        "log"
        // 導入相關包
        "gopkg.in/mgo.v2"
        "gopkg.in/mgo.v2/bson"
)

// 聲明一個結構體
type Person struct {
        Name string
        Phone string
}

func main() {
        // 連接MongoDB服務
        session, err := mgo.Dial("127.0.0.1:27017")
        if err != nil {
             panic(err)
        }
        defer session.Close()

        // 設置session的模式,不是必需的
        session.SetMode(mgo.Monotonic, true)

        // DB()方法切換到相應的數據庫,C()方法切換到相應的集合
        c := session.DB("test").C("people")

        // 插入兩條數據,Insert方法中的參數是不定參
        err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
               &Person{"Cla", "+55 53 8402 8510"})

        if err != nil {
             log.Fatal(err)
        }

        result := Person{}
        // 條件查詢,查詢 name 爲Ale的一條數據
        err = c.Find(bson.M{"name": "Ale"}).One(&result)
        if err != nil {
             log.Fatal(err)
        }

        fmt.Println("Phone:", result.Phone)
}

session 模式

  • Strong
    session 的讀寫一直向主服務器發起並使用一個唯一的連接,因此所有的讀寫操作完全的一致。

  • Monotonic
    session 的讀操作開始是向其他服務器發起(且通過一個唯一的連接),只要出現了一次寫操作,session 的連接就會切換至主服務器。由此可見此模式下,能夠分散一些讀操作到其他服務器,但是讀操作不一定能夠獲得最新的數據。

  • Eventual
    session 的讀操作會向任意的其他服務器發起,多次讀操作並不一定使用相同的連接,也就是讀操作不一定有序。session 的寫操作總是向主服務器發起,但是可能使用不同的連接,也就是寫操作也不一定有序。

CRUD操作

插入

使用Insert方法插入數據

c.Insert(&Person{"Ale",  "+55 53 8116 9639"}})

在MongoDB這種分佈式的數據庫中,ID並不是一個有序的整數,我們可以使用bson.NewObjectId()來手動創建一個新的ObjectId

c.Insert(&User{
    Id_:       bson.NewObjectId(),
    Name:      "Tracy Yu",
    Age:       31,
    JoinedAt:  time.Now(),
    Interests: []string{"Shoping", "TV"},
})

多條批量插入

var docs []interface{}
docs = append(docs, doc1)
docs = append(docs, doc2)
col.Insert(docs...)

刪除

使用Remove方法刪除單條數據,使用RemoveAll方法刪除所有的

刪除指定條件的數據

c.Remove(bson.M{"name": "Jimmy Kuu"})

修改

使用Update方法修改數據,如需更新所有的則可用UpdateAll() 方法

  • 修改字段值($set)

    c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, 
    	bson.M{"$set": bson.M{ "name": "Jimmy Gu", "age": 34, }})
    
  • 增加字段值($inc)

    c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, 
    	bson.M{"$inc": bson.M{ "age": -1, }})
    
  • 增加一個數組元素($push)

    c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, 
    	bson.M{"$push": bson.M{ "interests": "Golang", }})
    
  • 刪除一個數組元素($pull)

    c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")}, 
    	bson.M{"$pull": bson.M{ "interests": "Golang", }})
    

查詢

使用Collection對象的Find()方法查詢,並調用過濾方法返回結果

  • 無條件查詢
    All()方法可以獲得所有結果,One()只返回一個結果

    c.Find(nil).All(&users)
    
  • 條件查詢
    條件查詢使用bson.M{key: value}

    c.Find(bson.M{"name":  "Ale"}).One(&result)
    

    根據ObjectId查詢

    c.FindId(objectId).One(&user)
    
  • 多條件查詢

    • 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)
    
  • 其他

    • 查詢集合中的元素總數

      countNum, err := collection.Count()
      
    • 返回可迭代的結果

        iter := collection.Find(nil).Iter()
        for iter.Next(&result) {
            fmt.Printf("Result: %v\n", result.NAME)
        }
      

字段映射

使用結構體來插入數據時,會自動根據結構體字段名來生成數據庫字段,但由於Go語言要求結構體字段的首字母大寫才能訪問,當結構體中的字段定義與數據庫字段無法一致時,則可以使用Go語言的結構體Tag特性進行字段映射解決該問題。

結構體Tag類似於Java中的註解,使用反引號括起來,這裏通過字段映射直接指定數據庫中的字段

// 其中 bson 後面對應的字段爲數據庫中要生成的字段
type person struct {
    AGE    int    `bson:"age"`
    NAME   string `bson:"name"`
    HEIGHT int    `bson:"height"`
}

歡迎關注我的公衆號:編程之路從0到1

編程之路從0到1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章