Go語(yǔ)言使用MongoDB數(shù)據(jù)庫(kù)詳細(xì)步驟
MongoDB 安裝(Docker)
先裝個(gè) mongo,為了省事就用 docker 了。
docker 的 daemon.json 加一個(gè)國(guó)內(nèi)的源地址:
"registry-mirrors": [ "http://hub-mirror.c.163.com" ]
然后拉取 mongo 鏡像:
docker pull mongodb
啟動(dòng) mongo:
docker run -p 27017:27017 mongo
安裝 MongoDB Go 驅(qū)動(dòng)
go get go.mongodb.org/mongo-driver
基礎(chǔ)代碼
創(chuàng)建 main.go 文件,并且導(dǎo)入 bson
,mongo
和 mongo/options
包。
package main import( "context" "fmt" "log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) // 在后面的代碼中將會(huì)使用這個(gè) Trainer 結(jié)構(gòu)體 type Trainer struct { Name string Age int City string } func main() { // }
使用 Go Driver 連接到 MongoDB
一旦 MongoDB 的 Go 驅(qū)動(dòng)被導(dǎo)入之后,我們就可以使用 mongo.Connect
函數(shù)來(lái)連接到 MongoDB。你必須傳遞一個(gè) context
和 options.ClientOptions
對(duì)象給 mongo.Connect
函數(shù)。options.ClientOptions 被用來(lái)設(shè)置連接配置。
// 設(shè)置連接參數(shù) clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") // 連接到 MongoDB client, err := mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } // 檢查連接 err = client.Ping(context.TODO(), nil) if err != nil { log.Fatal(err) } fmt.Println("Connected to MongoDB!")
一旦你連接上了 MongoDB,你現(xiàn)在可以獲取 test 數(shù)據(jù)庫(kù)的 trainers 集合。
collection := client.Dataabse("test").Collection("trainers")
下面的代碼將會(huì)使用 collection
來(lái)查詢 trainers
集合。
如果你不在需要查詢 MongoDB,就可以使用 client.Disconnect()
來(lái)關(guān)閉 MongoDB 連接。
err = client.Disconnect(context.TODO()) if err != nil { log.Fatal(err) } fmt.Println("Connection to MongoDB closed.")
在 Go 里面使用 BSON 對(duì)象
在發(fā)送查詢請(qǐng)求到 MongoDB 之前,了解如何使用 BSON 對(duì)象是非常有必要的。在 MongoDB 中存儲(chǔ)的 JSON 文檔叫 BSON,是以二進(jìn)制形式存儲(chǔ)的。不像其他數(shù)據(jù)庫(kù)以字符串形式存儲(chǔ) JSOn 數(shù)據(jù),BSON 還包含了字段類型,這使得應(yīng)用程序更容易可靠地處理、排序和比較。Go 的 MongoDB 驅(qū)動(dòng)有兩個(gè)表示 BSON 數(shù)據(jù)的類型:D 類型和 Raw 類型。
D 類型用于使用 Go 中的原始類型來(lái)構(gòu)建 BSON 對(duì)象。這對(duì)于傳遞給 MongoDB 的命令特別有用。D 類型包括四種類型:
D:一個(gè) BSON 文檔。
M:無(wú)序的 map。
A:一個(gè) BSON 數(shù)組。
E:D 里面的單個(gè)元素。
這里是一個(gè)使用 D 類型篩選文檔的例子,這里會(huì)篩選出名字為 Alice 或者 Bob 的數(shù)據(jù):
bson.D({ "name", bson.D{ {"$in": bson.A{"Alice", "Bob"}} } })
CRUD 操作
一旦你連接到了數(shù)據(jù)庫(kù),我們就可以開始添加或者操作數(shù)據(jù)庫(kù)中的數(shù)據(jù)了。Collection
類型有一些方法允許你發(fā)送查詢到數(shù)據(jù)庫(kù)中。
插入文檔
首先,創(chuàng)建一些新的 Trainer
結(jié)構(gòu)體來(lái)插入到數(shù)據(jù)庫(kù)中:
ash := Trainer{"Ash", 10, "Pallet Town"} misty := Trainer{"Misty", 10, "Cerulean City"} brock := Trainer{"Brock", 15, "Pewter" City}
可以使用 collection.InsertOne()
方法來(lái)插入單個(gè)文檔:
insertResult, err := collection.InsertOne(context.TODO(), ash) if err != nil { log.Fatal(err) } fmt.Println("Inserted a single document: ", insertResult.InsertedID)
如果我們想一次性插入多個(gè)文檔,可以傳遞一個(gè)切片給 collection.InsertMany
方法:
trainers := []interface{}{misty, brock} insertManyResult, err := collection.InsertMany(context.TODO(), trainers) if err != nil { log.Fatal(err) } fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
更新文檔
collection.UpdateOne()
方法允許你更新單個(gè)文檔。它需要一個(gè) bson.D
類型的參數(shù)來(lái)篩選數(shù)據(jù)庫(kù)中特定的文檔,然后更新它。
// 篩選 name 字段的值為 Ash 的記錄 filter := bson.D{{"name", "Ash"}} // 更新 age 字段,值加 1 update := bson.D{ {"$inc", bson.D{ {"age", 1} }} }
這幾行代碼會(huì)將數(shù)據(jù)庫(kù)中名字為 Ash 的文檔的 age 字段的值加 1。
updateResult, err := collection.UpdateOne(context.TODO(), filter, update) if err != nil { log.Fatal(err) } fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)
查詢文檔
如果想要查詢一個(gè)文檔,同樣需要提供一個(gè) filter 文檔來(lái)篩選,同時(shí)需要一個(gè)接收結(jié)果的指針。為了查詢單個(gè)文檔,可以使用 collection.FindOne()
方法。這個(gè)方法會(huì)返回一條匹配上的記錄并解析到我們指針指向的地方。你可以使用和上面相同的 filter 來(lái)查詢 name 為 Ash 的記錄。
// 創(chuàng)建一個(gè)變量用來(lái)接收解析后的結(jié)果 var result Trainer err = collection.FindOne(context.TODO(), filter).Decode(&result) if err != nil { log.Fatal(err) } fmt.Printf("Found a single document: %+v\n", result)
如果想要查詢多個(gè)文檔,可以使用 collection.Find()
方法。這個(gè)方法返回一個(gè) Cursor
(游標(biāo))。一個(gè) Cursor
(游標(biāo))可以讓我們一次獲取到其中一條記錄。一旦一個(gè)游標(biāo)遍歷完畢,你應(yīng)該關(guān)閉這個(gè)游標(biāo)。
下面的例子中,我們?cè)?Find 的時(shí)候同時(shí)指定了額外的一些選項(xiàng),這里我們?cè)O(shè)置最多獲取的記錄數(shù)為 2。
// 這個(gè)選項(xiàng)會(huì)被傳遞給 Find 方法 findOptions := options.Find() findOptions.SetLimit(2) // 這是用來(lái)保存查詢結(jié)果的數(shù)組 var results []*Trainer // 傳遞 bson.D{{}} 作為 filter 來(lái)匹配 collection 中的所有文檔 cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions) if err != nil { log.Fatal(err) } // 查詢多個(gè)文檔的時(shí)候返回一個(gè) cursor // 迭代這個(gè) cursor 允許我們一次解碼一個(gè)文檔 for cur.Next(context.TODO()) { // 創(chuàng)建一個(gè)用來(lái)接收單個(gè)文檔的變量 var elem Trainer err := cur.Decode(&elem) if err != nil { log.Fatal(err) } results = append(results, &elem) } if err := cur.Err(); err != nil { log.Fatal(err) } // 一旦結(jié)束了獲取數(shù)據(jù)的操作,我們需要關(guān)閉 cursor cur.Close(context.TODO()) fmt.Println("Found multiple documents (array of pointers): %+v\n", results)
刪除文檔
最后,你可以使用 collection.DeleteOne()
或者 collection.DeleteMany()
來(lái)刪除文檔。這里傳遞了 bson.D{ {} }
作為 filter 參數(shù),將會(huì)匹配集合中的所有文檔。你也可以使用 collection.Drop
來(lái)刪除整個(gè)集合。
deleteResult, err := collection.DeleteMany(context.TODO(), bson.D{{}}) if err != nil { log.Fatal(err) } fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)
下一步
MongoDB Go 驅(qū)動(dòng)的完整文檔可以在 pkg.go.dev 中查看。
總結(jié)
到此這篇關(guān)于Go語(yǔ)言使用MongoDB數(shù)據(jù)庫(kù)的文章就介紹到這了,更多相關(guān)Go使用MongoDB內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Go語(yǔ)言實(shí)現(xiàn)選擇排序算法及優(yōu)化
選擇排序是一種簡(jiǎn)單的比較排序算法.這篇文章將利用Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法,文中的示例代碼講解詳細(xì),對(duì)學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下2022-12-12如何用go-zero 實(shí)現(xiàn)中臺(tái)系統(tǒng)
這篇文章主要介紹了如何用go-zero 實(shí)現(xiàn)中臺(tái)系統(tǒng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12GO語(yǔ)言的控制語(yǔ)句詳解包括GO語(yǔ)言的指針語(yǔ)法
這篇文章主要介紹了GO語(yǔ)言的控制語(yǔ)句詳解包括GO語(yǔ)言的指針語(yǔ)法,GO語(yǔ)言switch結(jié)構(gòu),GO語(yǔ)言for的4種結(jié)構(gòu)需要的朋友可以參考下2022-12-12golang time包下定時(shí)器的實(shí)現(xiàn)方法
定時(shí)器的實(shí)現(xiàn)大家應(yīng)該都遇到過(guò),最近在學(xué)習(xí)golang,所以下面這篇文章主要給大家介紹了關(guān)于golang time包下定時(shí)器的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-12-12基于go實(shí)例網(wǎng)絡(luò)存儲(chǔ)協(xié)議詳解
這篇文章主要為大家介紹了基于go實(shí)例網(wǎng)絡(luò)存儲(chǔ)協(xié)議詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03使用golang進(jìn)行http,get或postJson請(qǐng)求
這篇文章主要為大家詳細(xì)介紹了如何使用golang進(jìn)行http,get或postJson請(qǐng)求,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下2023-12-12