MongoDB Golang 驱动程序教程
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
多年来,MongoDB 一直依赖mgo和globalsign/mgo等社区驱动程序。去年,MongoDB宣布正在构建自己的解决方案。去年三月,他们发布了1.0.0 版本,那么让我们来看看如何使用官方驱动程序执行一些常规操作。
首先,你需要使用 go get 下载驱动程序。
go.mongodb.org/mongo-driver/mongo
假设您的 MongoDB 安装使用的是默认设置,那么您的方法应该如下所示:
package main
import (
"context"
"log"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func GetClient() *mongo.Client {
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.NewClient(clientOptions)
if err != nil {
log.Fatal(err)
}
err = client.Connect(context.Background())
if err != nil {
log.Fatal(err)
}
return client
}
为了测试与 MongoDB 的连接,我们可以调用一个名为 Ping 的函数,并检查它是否返回任何错误。如果没有错误,则表示连接成功。
func main() {
c := GetClient()
err := c.Ping(context.Background(), readpref.Primary())
if err != nil {
log.Fatal("Couldn't connect to the database", err)
} else {
log.Println("Connected!")
}
}
接下来,我创建了一个名为“database”的数据库civilact和一个集合heroes,并添加了以下文档:
{
"_id" : ObjectId("5d0574824d9f7ff15e989171"),
"name" : "Tony Stark",
"alias" : "Iron Man",
"signed" : true
}
{
"_id" : ObjectId("5d0574d74d9f7ff15e989172"),
"name" : "Steve Rodgers",
"alias" : "Captain America",
"signed" : false
}
{
"_id" : ObjectId("5d0574e94d9f7ff15e989173"),
"name" : "Vision",
"alias" : "Vision",
"signed" : true
}
{
"_id" : ObjectId("5d0575344d9f7ff15e989174"),
"name" : "Clint Barton",
"alias" : "Hawkeye",
"signed" : false
}
为了更好地处理这些文档,我们最好创建一个结构体来表示所有字段及其 JSON 名称。
type Hero struct {
Name string `json:"name"`
Alias string `json:"alias"`
Signed bool `json:"signed"`
}
现在我们创建一个方法,该方法返回所有英雄,它接受两个参数:MongoDB 客户端和一个表示筛选条件的 bson.M 对象。如果筛选条件为空,则该方法返回所有文档。
import (
"context"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func ReturnAllHeroes(client *mongo.Client, filter bson.M) []*Hero {
var heroes []*Hero
collection := client.Database("civilact").Collection("heroes")
cur, err := collection.Find(context.TODO(), filter)
if err != nil {
log.Fatal("Error on Finding all the documents", err)
}
for cur.Next(context.TODO()) {
var hero Hero
err = cur.Decode(&hero)
if err != nil {
log.Fatal("Error on Decoding the document", err)
}
heroes = append(heroes, &hero)
}
return heroes
}
具体构成如下:
- 创建一个
collection表示数据库中集合的元素; - 要求
collection返回一个包含基于筛选条件的元素的游标(在这种情况下,筛选条件为空,因此将返回所有元素); - 遍历此光标并将每个文档解码为 Hero 类型;
- 将解码后的英雄添加到
heroes数组中。
如果在主函数内部运行,返回结果将是:
heroes := ReturnAllHeroes(c, bson.M{})
for _, hero := range heroes {
log.Println(hero.Name, hero.Alias, hero.Signed)
}
2019/06/15 21:07:00 Tony Stark Iron Man true
2019/06/15 21:07:00 Steve Rodgers Captain America false
2019/06/15 21:07:00 Vision Vision true
2019/06/15 21:07:00 Clint Barton Hawkeye false
要只检索签署了索科维亚协议的英雄,我们只需要更改筛选条件。
heroes := ReturnAllHeroes(c, bson.M{"signed": true})
2019/06/15 21:18:04 Tony Stark Iron Man true
2019/06/15 21:18:04 Vision Vision true
如果只想检索一个英雄,我们的新方法如下:
func ReturnOneHero(client *mongo.Client, filter bson.M) Hero {
var hero Hero
collection := client.Database("civilact").Collection("heroes")
documentReturned := collection.FindOne(context.TODO(), filter)
documentReturned.Decode(&hero)
return hero
}
通话内容如下:
hero := ReturnOneHero(c, bson.M{"name": "Vision"})
log.Println(hero.Name, hero.Alias, hero.Signed)
2019/06/15 22:55:44 Vision Vision true
现在,为了扩充我们的英雄阵容,例如加入奇异博士,新的方法如下:
func InsertNewHero(client *mongo.Client, hero Hero) interface{} {
collection := client.Database("civilact").Collection("heroes")
insertResult, err := collection.InsertOne(context.TODO(), hero)
if err != nil {
log.Fatalln("Error on inserting new Hero", err)
}
return insertResult.InsertedID
}
这就是我们的方法将如何被之前的方法使用和检查的方式ReturnOneHero:
hero = Hero{Name: "Stephen Strange", Alias: "Doctor Strange", Signed: true}
insertedID := InsertNewHero(c, hero)
log.Println(insertedID)
hero = ReturnOneHero(c, bson.M{"alias": "Doctor Strange"})
log.Println(hero.Name, hero.Alias, hero.Signed)
太棒了!我们把一位至尊法师加入了我们的英雄收藏,但如果他不喜欢,要求我们把他从收藏中移除怎么办?嗯,这就是为什么我们需要一个RemoveOneHero方法。
func RemoveOneHero(client *mongo.Client, filter bson.M) int64 {
collection := client.Database("civilact").Collection("heroes")
deleteResult, err := collection.DeleteOne(context.TODO(), filter)
if err != nil {
log.Fatal("Error on deleting one Hero", err)
}
return deleteResult.DeletedCount
}
这就是我们的检查方法:
heroesRemoved := RemoveOneHero(c, bson.M{"alias": "Doctor Strange"})
log.Println("Heroes removed count:", heroesRemove
hero = ReturnOneHero(c, bson.M{"alias": "Doctor Strange"})
log.Println("Is Hero empty?", hero == Hero{ })
最后,我们假设鹰眼改变了主意,现在想要签署协议。那么,让我们来制定UpdateHero方法。
func UpdateHero(client *mongo.Client, updatedData bson.M, filter bson.M) int64 {
collection := client.Database("civilact").Collection("heroes")
atualizacao := bson.D{ {Key: "$set", Value: updatedData} }
updatedResult, err := collection.UpdateOne(context.TODO(), filter, atualizacao)
if err != nil {
log.Fatal("Error on updating one Hero", err)
}
return updatedResult.ModifiedCount
}
好了!常规的CRUD操作已经讲解完毕,我们的英雄们可以决定自己的命运了。
所有示例代码都可以在这里找到,本教程也发布在我的博客上。这是驱动程序的官方代码库和官方文档。
如果您有任何问题、建议或发现我的错误,请随时与我联系。
文章来源:https://dev.to/eduardohitek/mongodb-golang-driver-tutorial-49e5