Go語言中MongoDB的使用
關於MongoDB數據的基本介紹與環境搭建相關知識,可參見我的另一篇文章 文檔數據庫 MongoDB
環境準備
mgo簡介
mgo(音mango)是MongoDB的Go語言驅動,它用基於Go語法的簡單API實現了豐富的特性,並經過良好測試。
官方網站:http://labix.org/mgo
安裝
go get gopkg.in/mgo.v2
快速上手
mgo簡單操作步驟
- 導入mgo包
- 連接MongoDB服務
- 打開指定的數據庫,獲得一個Database對象(不存在則創建)
- 打開指定的集合,獲得一個Collection對象(不存在則創建)
- 調用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)
- and(
-
其他
-
查詢集合中的元素總數
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"`
}