Go语言实践篇之MongoDB
- 2019 年 10 月 4 日
- 筆記
- Go语言中MongoDB的使用
- 环境准备
- 安装
- 快速上手
- CRUD操作
- 插入
- 删除
- 修改
- 查询
- 字段映射
- 环境准备
Go语言中MongoDB的使用
关于MongoDB数据的基本介绍与环境搭建相关知识,可参见我的另一篇文章 文档数据库 MongoDB
环境准备
mgo简介 mgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API实现了丰富的特性,并经过良好测试。 官方网站:http://labix.org/mgo
API文档[1]
安装
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) - 多条件查询 c.Find(bson.M{"name": "Jimmy Kuu", "age": 33}).All(&users) c.Find(bson.M{"$or": []bson.M{bson.M{"name": "Jimmy Kuu"}, bson.M{"age": 31}}}).All(&users)
- or(
$or
) 多个条件中满足一个 - and(
$and
) 同时满足多个条件
- or(
- 其他
- 查询集合中的元素总数 countNum, err := collection.Count()
- 返回可迭代的结果 iter := collection.Find(nil).Iter() for iter.Next(&result) { fmt.Printf("Result: %vn", result.NAME) }
字段映射
使用结构体来插入数据时,会自动根据结构体字段名来生成数据库字段,但由于Go语言要求结构体字段的首字母大写才能访问,当结构体中的字段定义与数据库字段无法一致时,则可以使用Go语言的结构体Tag特性进行字段映射解决该问题。
结构体Tag类似于Java中的注解,使用反引号括起来,这里通过字段映射直接指定数据库中的字段
// 其中 bson 后面对应的字段为数据库中要生成的字段 type person struct { AGE int `bson:"age"` NAME string `bson:"name"` HEIGHT int `bson:"height"` }
参考资料
[1]
API文档: https://godoc.org/labix.org/v2/mgo#Bulk.Insert