Golang+MongoDB 從安裝到放棄


環境 Ubuntu16,MongoDB 4.2.2
官網:https://www.mongodb.com
官網下載地址:https://www.mongodb.com/download-center/community
官網安裝教程:https://docs.mongodb.com/manual/administration/install-community
官網shell命令文檔:https://docs.mongodb.com/manual/mongo
官網crud文檔:https://docs.mongodb.com/manual/crud

一、MongoDB介紹

MongoDB 是一個是一個基於分佈式文件存儲的數據庫,介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最像關係數據庫的。他支持的數據結構非常鬆散,是類似json的bson格式,因此可以存儲比較複雜的數據類型。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。

mongoDB中將一條數據存儲爲一個文檔(document),數據結構由鍵值(key-value)對組成。 其中文檔類似於我們平常編程中用到的JSON對象。 文檔中的字段值可以包含其他文檔,數組及文檔數組。

mongoDB相關概念

mongoDB中相關概念與我們熟悉的SQL概念對比如下:

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

二、安裝MongoDB

推薦手動安裝:手動教程
如果遇到錯誤請看這篇文章
如果mongo啓動報錯不知道爲什麼請看這篇文章
配置文件弄不明白的看這篇文章
配置文檔:

dbpath=/usr/local/mongodb/mongodbserver/data
logpath=/usr/local/mongodb/mongodbserver/logs/mongodb.log
logappend=true

fork=true        #後臺運行
journal=false
#quiet=true
#storageEngine=mmapv1

bind_ip=0.0.0.0  #允許任何IP進行連接
port=27017

auth=false       #是否授權連接

Ubuntu服務配置文檔
命令

vim /etc/init.d/mongodb
#!/bin/bash

start() {
/usr/local/mongodb/bin/mongod  --config /usr/local/mongodb/mongodbserver/etc/mongodb.conf
}

stop() {
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodbserver/etc/mongodb.conf --shutdown
}
case "${1:-''}" in
  'start')
 start
 ;;

'stop')
 stop
 ;;

'restart')
 stop
 start
 ;;
  *)
 echo  
$"Usage: $0 {start|stop|restart}"
 exit 1
esac

自動教程

ubuntu下安裝命令

sudo apt-get install -y mongodb

安裝完成後用下面的命令查看版本

mongo -version

啓動和關閉命令

service mongodb start
service mongodb stop

卸載命令

sudo apt-get --purge remove mongodb mongodb-clients mongodb-server

三、shell模式下MongoDB基本命令

進入MongoDB管理界面命令

mongo   //類似於mysql -uroot -p123

數據庫基本操作

show dbs         :顯示數據庫列表 
show collections :顯示當前數據庫中的集合(類似關係數據庫中的表table) 
show users       :顯示所有用戶 
use yourDB       :切換當前數據庫至yourDB 
db.help()        :顯示數據庫操作命令 
db.yourCollection.help() :顯示集合操作命令,yourCollection是集合名 

創建數據庫命令

use School #切換到School數據庫。MongoDB 無需預創建School數據庫,在使用時會自動創建

創建集合命令

db.createCollection('user') #創建一個聚集集合。MongoDB 其實在插入數據的時候,也會自動創建對應的集合,無需預定義集合

文檔的增刪改查

插入文檔

向集合中插入一條文檔

> db.user.insert({name:"wd",age:22})
WriteResult({ "nInserted" : 1 })

插入多條文檔

> db.user.insert([{name:"wyh",age:22},{name:"zjd",age:22}])
BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})

查尋

查詢一條

> db.user.find({name:"wd"})
{ "_id" : ObjectId("5df4a2c3690102e4083ad64c"), "name" : "wd", "age" : 22 }

查詢所有

> db.user.find()
{ "_id" : ObjectId("5df4a2c3690102e4083ad64c"), "name" : "wd", "age" : 22 }
{ "_id" : ObjectId("5df4a378690102e4083ad64d"), "name" : "wyh", "age" : 22 }
{ "_id" : ObjectId("5df4a378690102e4083ad64e"), "name" : "zjd", "age" : 22 }

其餘查詢命令

db.user.find()  #查詢所有記錄。相當於:select * from student
db.user.find({name: 'lisi'})  #查詢name='lisi'的記錄。相當於: select * from user where name='lisi'
db.user.find({},{name:1, age:1}) #查詢指定列name、age數據。相當於:select sname,sage from user 。name:1表示返回name列,默認_id字段也是返回的,可以添加_id:0(意爲不返回_id)寫成{name: 1, age: 1,_id:0},就不會返回默認的_id字段了
db.user.find({sname: 'zhangsan', sage: 22}) #and 與條件查詢。相當於:select * from user where sname = 'zhangsan' and sage = 22
db.user.find({$or: [{sage: 22}, {sage: 25}]}) #or 條件查詢。相當於:select * from user where sage = 22 or sage = 25
db.user.find({age:{$gt:20}})#大於查詢,相當於 select * from user where ago>20 

MongoDB符號對照表

> >= < <= !=
$gt $gte $lt $lte $ne

關係符號對照表

or in not in
$or $in $nin

更新文檔

函數原型

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

參數說明:

  • query : update的查詢條件,類似sql update查詢內where後面的。
  • update : update的對象和一些更新的操作符(如,,inc…)等,也可以理解爲sql update查詢內set後面的
  • upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入- objNew,true爲插入,默認是false,不插入。
  • multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數爲true,就把按條件查出來多條記錄全部更新。
  • writeConcern :可選,拋出異常的級別。

修改一條內容,若內容不存在,則放棄插入

//將年齡爲22的修改爲23
db.user.update({age:22},{age:23})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

修改一條內容,內容不存在 則新建

db.user.update({age:22},{name:"zly",age:22,like:"eat"},true)
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : ObjectId("5df5e05543101a8d2d42486c")
})

刪除文檔

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

參數說明:

  • query :(可選)刪除的文檔的條件。
  • justOne : (可選)如果設爲 true 或 1,則只刪除一個文檔,如果不設置該參數,或使用默認值 false,則刪除所有匹配條件的文檔。
  • writeConcern :(可選)拋出異常的級別。

刪除一條數據

db.user.remove({age:23},1)
WriteResult({ "nRemoved" : 1 })

其他常用命令

限制只查詢一條用limit(), 跳過指定條用 Skip()

db.user.find().limit(1)
{ "_id" : ObjectId("5df5e05543101a8d2d42486c"), "name" : "zly", "age" : 22, "like" : "eat" }

選擇排序方式 sort() 1 表示升序 -1 表示降序

 db.user.find().sort({age:-1})
{ "_id" : ObjectId("5df5e2a436ecef9359a3fc36"), "name" : "wd", "age" : 24, "like" : "study" }
{ "_id" : ObjectId("5df5e05543101a8d2d42486c"), "name" : "zly", "age" : 22, "like" : "eat" }
索引
db.user.createIndex({"name":1})  //爲name字段創建索引,1爲升序,-1爲降序
db.user.createIndex({"name":-1},{unique:true}) //創建一個值不能重複的索引
db.user.createIndex({"createDate":1},{expireAfterSeconds:10}) //定時刪除數據索引 createDate必須爲日期類型
db.user.getIndexes()         //查看集合所有索引
db.user.totalIndexSize()     //查看索引大小
db.user.dropIndex("name_1")  //刪除索引
db.user.dropIndexes()        //刪除所有索引

Golang操作MongoDB

工具下載地址:github.com/mongodb/mongo-go-driver
推薦文檔:https://docs.mongodb.com/manual/reference/connection-string/
官方插件說明文檔:https://godoc.org/go.mongodb.org/mongo-driver/mongo
參考大神文章(英):https://www.cnblogs.com/endurance9/p/10409232.html
李老師文章(中):
https://www.liwenzhou.com/posts/Go/go_mongodb/

推薦使用官網的包,也可以用第三方插件mgo

首先 創建庫 創建用戶用於遠程連接

> use school
> use admin
> db.createUser({user:"wd",pwd:"123",roles:[{role:"readWrite",db:"school"}]})
> db.system.users.find() //查看用戶
> 權限說明
    1. 數據庫用戶角色:read、readWrite;
    2. 數據庫管理角色:dbAdmin、dbOwner、userAdmin;
    3. 集羣管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
    4. 備份恢復角色:backup、restore;
    5. 所有數據庫角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    6. 超級用戶角色:root  

創建複雜權限方法見連接:http://www.voidcn.com/article/p-stetasvk-bhr.html
創建完成後,修改配置文件,默認在/etc/下面,複製上面的配置。重啓服務。

MongoDB連接標準語法:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
  • mongodb:// 這是固定的格式,必須要指定。
  • username:password@ 可選項,如果設置,在連接數據庫服務器之後,驅動都會嘗試登陸這個數據庫
  • host1 必須的指定至少一個host, host1 是這個URI唯一要填寫的。它指定了要連接服務器的地址。如果要連接複製集,請指定多個主機地址。
  • portX 可選的指定端口,如果不填,默認爲27017
  • /database 如果指定username:password@,連接並驗證登陸指定數據庫。若不指定,默認打開 test 數據庫。
  • ?options 是連接選項。如果不使用/database,則前面需要加上/。所有連接選項都是鍵值對name=value,鍵值對之間通過&或;(分號)隔開
    不bb,上代碼

簡單連接栗子

package main

import (
	"context"
	"fmt"
	"log"

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

func main() {
	// 設置客戶端連接配置
	ctx, mongoclos := context.WithCancel(context.Background())
	defer mongoclos()
	//先在數據庫設置用戶名密碼,再用MongoDB Compass測試一下是否能夠連接,再用代碼測試
	clientOptions := options.Client().ApplyURI(`mongodb://wd:[email protected]:27017/school`)

	// 連接到MongoDB
	client, err := mongo.Connect(ctx, clientOptions)
	if err != nil {
		log.Fatal(err)
	}
	// 檢查連接
	err = client.Ping(ctx, nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Connected to MongoDB!")
}

斷開連接代碼

	err = client.Disconnect(ctx)
	if err != nil {
		log.Printf(err.Error())
	}
	fmt.Println("Connection to MongoDB closed.")

插入一條數據

//Student 學生結構體
type Student struct {
	Name string
	Age  int
	Like string
}
	students := client.Database("school").Collection("student")
	s1 := Student{
		Name: "wyh",
		Age:  23,
		Like: "study",
	}
	res, err := students.InsertOne(context.TODO(), s1)
	if err != nil {
		log.Println(err.Error())
	} else {
		log.Println(res.InsertedID)
	}

插入後的截圖
在這裏插入圖片描述

BSON簡介

官方說明:http://bsonspec.org/#/specification
bson包說明:https://godoc.org/github.com/globalsign/mgo/bson
MongoDB中的JSON文檔存儲在名爲BSON(二進制編碼的JSON)的二進制表示中。與其他將JSON數據存儲爲簡單字符串和數字的數據庫不同,BSON編碼擴展了JSON表示,使其包含額外的類型,如int、long、date、浮點數和decimal128。這使得應用程序更容易可靠地處理、排序和比較數據。

連接MongoDB的Go驅動程序中有兩大類型表示BSON數據:D和Raw。

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

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

修改一條數據

	query := bson.D{{"name", "wyh"}}
	info := bson.D{{"$set", bson.D{{"age", 666}}}}
	//此處用的Many,如無必要,儘量用one
	res, err := students.UpdateMany(context.TODO(), query, info)
	if err != nil {
		log.Println(err.Error())
	} else {
		log.Println(res.ModifiedCount)
	}

再查看一下,age變成了666
在這裏插入圖片描述
查詢一條數據,查詢多條的用法和sql的方式一樣

	var stu Student
	query := bson.D{{"name", "wyh"}}
	err = students.FindOne(context.TODO(), query).Decode(&stu)
	if err != io.EOF && err != nil {
		log.Fatalln(err)
	}
	log.Println(stu)

結果截圖
在這裏插入圖片描述
刪除一條文檔

	query := bson.D{{"name", "wd"}}
	res, err := students.DeleteOne(context.TODO(), query)
	if err != nil {
		log.Fatalln(err)
	}
	log.Println(res.DeletedCount)

結果
在這裏插入圖片描述

用過sql包的應該可以很快上手,這裏再簡單說明一下
mongo包的函數參數

filter interface{}  //一般對應一個bson結構,通常作爲條件使用
documents interface{} //一般爲對應結構體
opts ...*options.xxxxxxx  一般爲參數設置,用法如下
//--------------設置最大查詢時間,也可以設置其他參數----------
	//fops := options.FindOne().SetMaxTime(time.Millisecond * 200)
	fops := options.FindOne()
	maxtime := time.Second * 3
	fops.MaxTime = &maxtime
	err = students.FindOne(ctx, query, fops).Decode(&stu)

大文件讀寫

單個文件上傳大小最多是16M,這是bson的最大容量,如果想上傳大於16m文件,可以用mongo下面的gridfs包

	//打開一個文件讀到內存中,也可以直接外存上傳
	file, err := ioutil.ReadFile("D:/code/test.mp4")
	if err != nil {
		log.Fatalln(err)
	}
	//聲明一個桶,嗯~~~,和分佈式文件存儲呼應上了
	b, err := gridfs.NewBucket(client.Database("school"))
	if err != nil {
		log.Fatalln(err)
	}
	//實例一個上傳流,並將上面獲取的內容寫入,“test.mp4”是文件在數據庫中的名字,
	us, err := b.OpenUploadStream("test.mp4")
	_, err = us.Write(file)
	if err != nil {
		log.Fatalln(err)
	}
	us.Close()
	//創建一個文件
	nfile, err := os.OpenFile("D:/test.mp4", os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalln(err)
	}
	//直接將得到的文件寫入剛纔創建的文件中。
	_, err = b.DownloadToStreamByName("test.mp4", nfile)
	nfile.Close()

重新連接compass
在這裏插入圖片描述

  • fs.chunks 是文件具體的存放地點
  • fs.files 是文件的列表

list中可以看見我們的文件,之後上傳的文件會被追加進這兩個集合中。

尾語

關於mongodb副本集配置參考文檔:https://www.cnblogs.com/Joans/p/7680846.html
關於mongodb分片集配置參考文檔:https://www.cnblogs.com/wggj/p/8391458.html

未完待續…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章