Go語言操做mongoDB

Go語言操做mongoDB

mongoDB是目前比較流行的一個基於分佈式文件存儲的數據庫,它是一個介於關係數據庫和非關係數據庫(NoSQL)之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。git

mongoDB介紹

mongoDB是目前比較流行的一個基於分佈式文件存儲的數據庫,它是一個介於關係數據庫和非關係數據庫(NoSQL)之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。github

mongoDB中將一條數據存儲爲一個文檔(document),數據結構由鍵值(key-value)對組成。 其中文檔相似於咱們日常編程中用到的JSON對象。 文檔中的字段值能夠包含其餘文檔,數組及文檔數組。mongodb

mongoDB相關概念

mongoDB中相關概念與咱們熟悉的SQL概念對好比下:shell

MongoDB術語/概念 說明 對比SQL術語/概念
database 數據庫 database
collection 集合 table
document 文檔 row
field 字段 column
index index 索引
primary key 主鍵 MongoDB自動將_id字段設置爲主鍵 primary key

mongoDB安裝

咱們這裏下載和安裝社區版,官網下載地址。 打開上述鏈接後,選擇對應的版本、操做系統平臺(常見的平臺均支持)和包類型,點擊Download按鈕下載便可。數據庫

這裏補充說明下,Windows平臺有ZIPMSI兩種包類型: * ZIP:壓縮文件版本 * MSI:可執行文件版本,點擊」下一步」安裝便可。編程

macOS平臺除了在該網頁下載TGZ文件外,還可使用Homebrew安裝。windows

更多安裝細節能夠參考官方安裝教程,裏面有LinuxmacOSWindows三大主流平臺的安裝教程。數組

mongoDB基本使用

啓動mongoDB數據庫

Windows

"C:\Program Files\MongoDB\Server\4.2\bin\mongod.exe" --dbpath="c:\data\db"

Mac

mongod --config /usr/local/etc/mongod.conf

bash

brew services start mongodb-community@4.2

啓動client

Windows

"C:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"

Mac

mongo

數據庫經常使用命令

show dbs;:查看數據庫數據結構

> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

use q1mi;:切換到指定數據庫,若是不存在該數據庫就建立。

> use q1mi;
switched to db q1mi

db;:顯示當前所在數據庫。

> db;
q1mi

db.dropDatabase():刪除當前數據庫

> db.dropDatabase();
{ "ok" : 1 }

數據集經常使用命令

db.createCollection(name,options):建立數據集

  • name:數據集名稱
  • options:可選參數,指定內存大小和索引。
> db.createCollection("student");
{ "ok" : 1 }

show collections;:查看當前數據庫中全部集合。

> show collections;
student

db.student.drop():刪除指定數據集

> db.student.drop()
true

文檔經常使用命令

插入一條文檔:

> db.student.insertOne({name:"小王子",age:18});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5db149e904b33457f8c02509")
}

插入多條文檔:

> db.student.insertMany([
... {name:"張三",age:20},
... {name:"李四",age:25}
... ]);
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5db14c4704b33457f8c0250a"),
        ObjectId("5db14c4704b33457f8c0250b")
    ]
}

查詢全部文檔:

> db.student.find();
{ "_id" : ObjectId("5db149e904b33457f8c02509"), "name" : "小王子", "age" : 18 }
{ "_id" : ObjectId("5db14c4704b33457f8c0250a"), "name" : "張三", "age" : 20 }
{ "_id" : ObjectId("5db14c4704b33457f8c0250b"), "name" : "李四", "age" : 25 }

查詢age>20歲的文檔:

> db.student.find(
... {age:{$gt:20}}
... )
{ "_id" : ObjectId("5db14c4704b33457f8c0250b"), "name" : "李四", "age" : 25 }

更新文檔:

> db.student.update(
... {name:"小王子"},
... {name:"老王子",age:98}
... );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.student.find()
{ "_id" : ObjectId("5db149e904b33457f8c02509"), "name" : "老王子", "age" : 98 }
{ "_id" : ObjectId("5db14c4704b33457f8c0250a"), "name" : "張三", "age" : 20 }
{ "_id" : ObjectId("5db14c4704b33457f8c0250b"), "name" : "李四", "age" : 25 }

刪除文檔:

> db.student.deleteOne({name:"李四"});
{ "acknowledged" : true, "deletedCount" : 1 }
> db.student.find()
{ "_id" : ObjectId("5db149e904b33457f8c02509"), "name" : "老王子", "age" : 98 }
{ "_id" : ObjectId("5db14c4704b33457f8c0250a"), "name" : "張三", "age" : 20 }

命令實在太多,更多命令請參閱官方文檔:shell命令官方文檔:CRUD操做

Go語言操做mongoDB

咱們這裏使用的是官方的驅動包,固然你也可使用第三方的驅動包(如mgo等)。 mongoDB官方版的Go驅動發佈的比較晚(2018年12月13號)。

安裝mongoDB Go驅動包

go get github.com/mongodb/mongo-go-driver

經過Go代碼鏈接mongoDB

package main

import (
    "context"
    "fmt"
    "log"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    // 設置客戶端鏈接配置
    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以後,能夠經過下面的語句處理咱們上面的q1mi數據庫中的student數據集了:

// 指定獲取要操做的數據集
collection := client.Database("q1mi").Collection("student")

處理完任務以後能夠經過下面的命令斷開與MongoDB的鏈接:

// 斷開鏈接
err = client.Disconnect(context.TODO())
if err != nil {
    log.Fatal(err)
}
fmt.Println("Connection to MongoDB closed.")

BSON

MongoDB中的JSON文檔存儲在名爲BSON(二進制編碼的JSON)的二進制表示中。與其餘將JSON數據存儲爲簡單字符串和數字的數據庫不一樣,BSON編碼擴展了JSON表示,使其包含額外的類型,如int、long、date、浮點數和decimal128。這使得應用程序更容易可靠地處理、排序和比較數據。

鏈接MongoDB的Go驅動程序中有兩大類型表示BSON數據:DRaw

類型D家族被用來簡潔地構建使用本地Go類型的BSON對象。這對於構造傳遞給MongoDB的命令特別有用。D家族包括四類:

  • D:一個BSON文檔。這種類型應該在順序重要的狀況下使用,好比MongoDB命令。
  • M:一張無序的map。它和D是同樣的,只是它不保持順序。
  • A:一個BSON數組。
  • E:D裏面的一個元素。

要使用BSON,須要先導入下面的包:

import "go.mongodb.org/mongo-driver/bson"

下面是一個使用D類型構建的過濾器文檔的例子,它能夠用來查找name字段與’張三’或’李四’匹配的文檔:

bson.D{{
    "name",
    bson.D{{
        "$in",
        bson.A{"張三", "李四"},
    }},
}}

Raw類型家族用於驗證字節切片。你還可使用Lookup()從原始類型檢索單個元素。若是你不想要將BSON反序列化成另外一種類型的開銷,那麼這是很是有用的。這個教程咱們將只使用D類型。

CRUD

咱們如今Go代碼中定義一個Studet類型以下:

type Student struct {
    Name string
    Age int
}

接下來,建立一些Student類型的值,準備插入到數據庫中:

s1 := Student{"小紅", 12}
s2 := Student{"小蘭", 10}
s3 := Student{"小黃", 11}

插入文檔

使用collection.InsertOne()方法插入一條文檔記錄:

insertResult, err := collection.InsertOne(context.TODO(), s1)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted a single document: ", insertResult.InsertedID)

使用collection.InsertMany()方法插入多條文檔記錄:

students := []interface{}{s2, s3}
insertManyResult, err := collection.InsertMany(context.TODO(), students)
if err != nil {
    log.Fatal(err)
}
fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)

更新文檔

updateone()方法容許你更新單個文檔。它須要一個篩選器文檔來匹配數據庫中的文檔,並須要一個更新文檔來描述更新操做。你可使用bson.D類型來構建篩選文檔和更新文檔:

filter := bson.D{{"name", "小蘭"}}

update := bson.D{
    {"$inc", bson.D{
        {"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)

查找文檔

要找到一個文檔,你須要一個filter文檔,以及一個指向能夠將結果解碼爲其值的指針。要查找單個文檔,使用collection.FindOne()。這個方法返回一個能夠解碼爲值的結果。

咱們使用上面定義過的那個filter來查找姓名爲’小蘭’的文檔。

// 建立一個Student變量用來接收查詢的結果
var result Student
err = collection.FindOne(context.TODO(), filter).Decode(&result)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Found a single document: %+v\n", result)

要查找多個文檔,請使用collection.Find()。此方法返回一個遊標。遊標提供了一個文檔流,你能夠經過它一次迭代和解碼一個文檔。當遊標用完以後,應該關閉遊標。下面的示例將使用options包設置一個限制以便只返回兩個文檔。

// 查詢多個
// 將選項傳遞給Find()
findOptions := options.Find()
findOptions.SetLimit(2)

// 定義一個切片用來存儲查詢結果
var results []*Student

// 把bson.D{{}}做爲一個filter來匹配全部文檔
cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions)
if err != nil {
    log.Fatal(err)
}

// 查找多個文檔返回一個光標
// 遍歷遊標容許咱們一次解碼一個文檔
for cur.Next(context.TODO()) {
    // 建立一個值,將單個文檔解碼爲該值
    var elem Student
    err := cur.Decode(&elem)
    if err != nil {
        log.Fatal(err)
    }
    results = append(results, &elem)
}

if err := cur.Err(); err != nil {
    log.Fatal(err)
}

// 完成後關閉遊標
cur.Close(context.TODO())
fmt.Printf("Found multiple documents (array of pointers): %#v\n", results)

刪除文檔

最後,可使用collection.DeleteOne()collection.DeleteMany()刪除文檔。若是你傳遞bson.D{{}}做爲過濾器參數,它將匹配數據集中的全部文檔。還可使用collection. drop()刪除整個數據集。

// 刪除名字是小黃的那個
deleteResult1, err := collection.DeleteOne(context.TODO(), bson.D{{"name","小黃"}})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult1.DeletedCount)
// 刪除全部
deleteResult2, err := collection.DeleteMany(context.TODO(), bson.D{{}})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult2.DeletedCount)

更多方法請查閱官方文檔

參考連接

https://docs.mongodb.com/manual/mongo/

https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial

相關文章
相關標籤/搜索