Golang学习系列第六天:操作MongoDB
0. ssh连接linux(我用的centos7),略
1. 安装MongoDB
可以直接到MongoDB官网https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat-tarball/根据样板安装:,可根据自己的电脑操作系统下载对应的版本,我下载的是mongodb-linux-x86_64-4.0.0.tgz安装包,不过也可以直接点击下面这个链接直接下载 https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.0.tgz,即
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.0.tgz
下载完毕后解压缩
[root@master dgm]# tar -zxf mongodb-linux-x86_64-4.0.0.tgz
名字那么长,可以进行重命名:
[root@master dgm]# mv mongodb-linux-x86_64-4.0.0 mongodb
进入到mongodb主目录下:
cd mongodb
分别建配置文件、数据目录、日志文件
建立配置文件
vim mongodb.conf
键入以下内容
#端口号
port=27017
#db目录
dbpath=/dgm/mongodb/data/db
#日志目录
logpath=/dgm/mongodb/logs/mongodb.log
#后台
fork=true
#日志输出
logappend=true
#允许远程IP连接
bind_ip=0.0.0.0
注意路径根据自己电脑的实际情况填写
建立数据目录和日志文件
[root@master mongodb]# mkdir -p data/db logs
[root@master mongodb]# touch logs/mongodb.log
编辑环境配置
vim /etc/profile
追加以下内容:
切记路径按实际情况写
source /etc/profile
启动mongodb测试
[root@master mongodb]# mongod --config mongodb.conf
最后连接测试
[root@master mongodb]# mongo
为了安全起见,我们需要设置相应的用户名和密码。
创建数据库系统管理员
> use admin
switched to db admin
> db.createUser({ user: "admin", pwd: "12345678", roles: [{ role: "userAdminAnyDatabase", db: "admin" }] })
Successfully added user: {"user" : "admin","roles" : [{"role" : "userAdminAnyDatabase","db" : "admin"}]
}
> db.auth("admin", "12345678")
1
修改mongodb配置追加认证标志
## 是否以安全认证方式运行,默认是不认证的非安全方式
#noauth = true
auth = true
然后重启mongodb服务
再次通过shell进入mongodb,创建需要管理的mongodb 数据的账号密码,此处是库是douyin,用户名是root,密码87654321
[root@master mongorest]# mongo
> use admin
switched to db admin
> db.auth("admin", "12345678")
1
> use douyin
switched to db douyin
> db.createUser({ user: "root", pwd: "87654321", roles: [{ role: "dbOwner", db: "douyin" }] })
Successfully added user: {"user" : "root","roles" : [{"role" : "dbOwner","db" : "douyin"}]
}
> use admin
switched to db admin
> db.system.users.find()
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "Qp+6YETcIsDyrPPwQVtWHQ==", "storedKey" : "0X27QePHJknrd+5qg4Ai5TeEWjg=", "serverKey" : "ZYRXkrQfJY875GC1qf76xAmBFow=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "E3LYqVegf93pTNjwNqXh4Gy8zQ1qNXXz0HtHHw==", "storedKey" : "yUZq7I9/w8Kf6fLu6Q8OqJcKNv77KUDmvGo4gEGi5ng=", "serverKey" : "+sNL0T/gfa+B+HoNSeid+HCC7OulvZlvSi2FDtE3wfk=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "douyin.root", "user" : "root", "db" : "douyin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "gVHTUMMMC38slLBW15kxPw==", "storedKey" : "591b17pCtkEZcVXf7ZO/Ll4DPAs=", "serverKey" : "vd5w+StBi9eXfViwWY30tc66lmo=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "2CHwq56N9MLts2v+PSqN3qs6tpWX1BKHY0aTDA==", "storedKey" : "2v5I/nnNoGVst2tTljoQs34z7bDNZS4euv6nAFZGxyc=", "serverKey" : "/F2xcR86DH4ErEEEbDyprmm1ttnl1o6sniWrj3vjjTY=" } }, "roles" : [ { "role" : "dbOwner", "db" : "douyin" } ] }
> exit
测试密码权限是否生效
先看失败的尝试案例
[root@master mongorest]# mongo
MongoDB shell version v4.0.0
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.0
> use douyin
switched to db douyin
> show collections
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
> db.douyin.find()
Error: error: {"ok" : 0,"errmsg" : "command find requires authentication","code" : 13,"codeName" : "Unauthorized"
}
>
再看成功的案例
[root@master mongorest]# mongo "mongodb://root:87654321@127.0.0.1:27017/douyin"
MongoDB shell version v4.0.0
connecting to: mongodb://127.0.0.1:27017/douyin
MongoDB server version: 4.0.0
> show collections
douyin
> db.douyin.find()
{ "_id" : ObjectId("5f083625b8b307c7e889f276") }
{ "_id" : ObjectId("5f08365cb8b307c7e889f277"), "name" : "dongguangming", "age" : 31 }
>
很好,权限认证通过了,可以查询数据记录
2. golang操作MongoDB
2.1 增加书籍接口
新建go文件mongdb-add.go,键入以下代码
package mainimport ("encoding/json""fmt""log""net/http""goji.io""goji.io/pat""gopkg.in/mgo.v2"
)func ErrorWithJSON(w http.ResponseWriter, message string, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)fmt.Fprintf(w, "{message: %q}", message)
}func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)w.Write(json)
}type Book struct {ISBN string `json:"isbn"`Title string `json:"title"`Authors []string `json:"authors"`Price string `json:"price"`
}func main() {session, err := mgo.Dial("mongodb://root:87654321@127.0.0.1:27017/douyin")if err != nil {panic(err)}defer session.Close()session.SetMode(mgo.Monotonic, true)ensureIndex(session)mux := goji.NewMux()mux.HandleFunc(pat.Post("/books"), addBook(session))http.ListenAndServe("192.168.8.200:8888", mux)
}func ensureIndex(s *mgo.Session) {session := s.Copy()defer session.Close()c := session.DB("douyin").C("books")index := mgo.Index{Key: []string{"isbn"},Unique: true,DropDups: true,Background: true,Sparse: true,}err := c.EnsureIndex(index)if err != nil {panic(err)}
}func addBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {session := s.Copy()defer session.Close()var book Bookdecoder := json.NewDecoder(r.Body)err := decoder.Decode(&book)if err != nil {ErrorWithJSON(w, "数据格式不对", http.StatusBadRequest)return}c := session.DB("douyin").C("books")err = c.Insert(book)if err != nil {if mgo.IsDup(err) {ErrorWithJSON(w, "书的isbn已存在", http.StatusBadRequest)return}ErrorWithJSON(w, "服务器错误", http.StatusInternalServerError)log.Println("添加书失败!!!: ", err)return}w.Header().Set("Content-Type", "application/json")w.Header().Set("Location", r.URL.Path+"/"+book.ISBN)w.WriteHeader(http.StatusCreated)}
}
然后就就执行以上程序,
go run mongdb-add.go
打开postman测试
查询数据库是否已存在
2.2 查询单书籍接口
新建go文件mongdb-select.go,键入以下代码
package mainimport ("encoding/json""fmt""log""net/http""goji.io""goji.io/pat""gopkg.in/mgo.v2""gopkg.in/mgo.v2/bson"
)func ErrorWithJSON(w http.ResponseWriter, message string, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)fmt.Fprintf(w, "{message: %q}", message)
}func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)w.Write(json)
}type Book struct {ISBN string `json:"isbn"`Title string `json:"title"`Authors []string `json:"authors"`Price string `json:"price"`
}func main() {session, err := mgo.Dial("mongodb://root:87654321@127.0.0.1:27017/douyin")if err != nil {panic(err)}defer session.Close()session.SetMode(mgo.Monotonic, true)ensureIndex(session)mux := goji.NewMux()mux.HandleFunc(pat.Get("/books/:isbn"), bookByISBN(session)) http.ListenAndServe("192.168.8.200:8888", mux)
}func ensureIndex(s *mgo.Session) {session := s.Copy()defer session.Close()c := session.DB("douyin").C("books")index := mgo.Index{Key: []string{"isbn"},Unique: true,DropDups: true,Background: true,Sparse: true,}err := c.EnsureIndex(index)if err != nil {panic(err)}
}func bookByISBN(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {session := s.Copy()defer session.Close()isbn := pat.Param(r, "isbn")c := session.DB("store").C("books")var book Bookerr := c.Find(bson.M{"isbn": isbn}).One(&book)if err != nil {ErrorWithJSON(w, "数据库错误", http.StatusInternalServerError)log.Println("查找isbn的书失败: ", err)return}if book.ISBN == "" {ErrorWithJSON(w, "书不存在", http.StatusNotFound)return}respBody, err := json.MarshalIndent(book, "", " ")if err != nil {log.Fatal(err)}ResponseWithJSON(w, respBody, http.StatusOK)}
}
执行程序
go run mongdb-select.go
继续用postman测试接口
2.3 修改单书籍接口
新建go文件mongdb-update.go,键入以下代码
package mainimport ("encoding/json""fmt""log""net/http""goji.io""goji.io/pat""gopkg.in/mgo.v2""gopkg.in/mgo.v2/bson"
)func ErrorWithJSON(w http.ResponseWriter, message string, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)fmt.Fprintf(w, "{message: %q}", message)
}func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)w.Write(json)
}type Book struct {ISBN string `json:"isbn"`Title string `json:"title"`Authors []string `json:"authors"`Price string `json:"price"`
}func main() {session, err := mgo.Dial("mongodb://root:87654321@127.0.0.1:27017/douyin")if err != nil {panic(err)}defer session.Close()session.SetMode(mgo.Monotonic, true)ensureIndex(session)mux := goji.NewMux()mux.HandleFunc(pat.Put("/books/:isbn"), updateBook(session)) http.ListenAndServe("192.168.8.200:8888", mux)
}func ensureIndex(s *mgo.Session) {session := s.Copy()defer session.Close()c := session.DB("douyin").C("books")index := mgo.Index{Key: []string{"isbn"},Unique: true,DropDups: true,Background: true,Sparse: true,}err := c.EnsureIndex(index)if err != nil {panic(err)}
}func updateBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {session := s.Copy()defer session.Close()isbn := pat.Param(r, "isbn")var book Bookdecoder := json.NewDecoder(r.Body)err := decoder.Decode(&book)if err != nil {ErrorWithJSON(w, "Incorrect body", http.StatusBadRequest)return}c := session.DB("douyin").C("books")err = c.Update(bson.M{"isbn": isbn}, &book)if err != nil {switch err {default:ErrorWithJSON(w, "Database error", http.StatusInternalServerError)log.Println("Failed update book: ", err)returncase mgo.ErrNotFound:ErrorWithJSON(w, "Book not found", http.StatusNotFound)return}}w.WriteHeader(http.StatusNoContent)}
}
执行以上程序
go run mongdb-update.go
postman继续测试
再此查询isbn为1234567890的信息
2.4 查询所有书籍接口
新建go文件mongdb-all.go,键入以下代码
package mainimport ("encoding/json""fmt""log""net/http""goji.io""goji.io/pat""gopkg.in/mgo.v2""gopkg.in/mgo.v2/bson"
)func ErrorWithJSON(w http.ResponseWriter, message string, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)fmt.Fprintf(w, "{message: %q}", message)
}func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)w.Write(json)
}type Book struct {ISBN string `json:"isbn"`Title string `json:"title"`Authors []string `json:"authors"`Price string `json:"price"`
}func main() {session, err := mgo.Dial("mongodb://root:87654321@127.0.0.1:27017/douyin")if err != nil {panic(err)}defer session.Close()session.SetMode(mgo.Monotonic, true)ensureIndex(session)mux := goji.NewMux()mux.HandleFunc(pat.Get("/books"), allBooks(session))http.ListenAndServe("192.168.8.200:8889", mux)
}func ensureIndex(s *mgo.Session) {session := s.Copy()defer session.Close()c := session.DB("douyin").C("books")index := mgo.Index{Key: []string{"isbn"},Unique: true,DropDups: true,Background: true,Sparse: true,}err := c.EnsureIndex(index)if err != nil {panic(err)}
}func allBooks(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {session := s.Copy()defer session.Close()c := session.DB("douyin").C("books")var books []Bookerr := c.Find(bson.M{}).All(&books)if err != nil {ErrorWithJSON(w, "Database error", http.StatusInternalServerError)log.Println("Failed get all books: ", err)return}respBody, err := json.MarshalIndent(books, "", " ")if err != nil {log.Fatal(err)}ResponseWithJSON(w, respBody, http.StatusOK)}
}
运行该程序
go run mongdb-all.go
打开postman或浏览器
2.5 删除单书籍接口
新建go文件mongdb-delete.go(根据isbn编号),键入以下代码
package mainimport ("fmt""log""net/http""goji.io""goji.io/pat""gopkg.in/mgo.v2""gopkg.in/mgo.v2/bson"
)func ErrorWithJSON(w http.ResponseWriter, message string, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)fmt.Fprintf(w, "{message: %q}", message)
}func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {w.Header().Set("Content-Type", "application/json; charset=utf-8")w.WriteHeader(code)w.Write(json)
}type Book struct {ISBN string `json:"isbn"`Title string `json:"title"`Authors []string `json:"authors"`Price string `json:"price"`
}func main() {session, err := mgo.Dial("mongodb://root:87654321@127.0.0.1:27017/douyin")if err != nil {panic(err)}defer session.Close()session.SetMode(mgo.Monotonic, true)ensureIndex(session)mux := goji.NewMux()mux.HandleFunc(pat.Delete("/books/:isbn"), deleteBook(session))http.ListenAndServe("192.168.8.200:8889", mux)
}func ensureIndex(s *mgo.Session) {session := s.Copy()defer session.Close()c := session.DB("douyin").C("books")index := mgo.Index{Key: []string{"isbn"},Unique: true,DropDups: true,Background: true,Sparse: true,}err := c.EnsureIndex(index)if err != nil {panic(err)}
}
func deleteBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {session := s.Copy()defer session.Close()isbn := pat.Param(r, "isbn")c := session.DB("douyin").C("books")err := c.Remove(bson.M{"isbn": isbn})if err != nil {switch err {default:ErrorWithJSON(w, "Database error", http.StatusInternalServerError)log.Println("Failed delete book: ", err)returncase mgo.ErrNotFound:ErrorWithJSON(w, "Book not found", http.StatusNotFound)return}}w.WriteHeader(http.StatusNoContent)}
}
执行以上程序
go run mongdb-delete.go
用postman测试删除
然后去数据库查看是否还有该isbn为1234567890的书籍
最后加上一点,mongodb和其他数据库mysql、postgresql一样面临数据多需要分页的情况,类比2012年做的车辆GPS+3G视频监控调度系统(每辆车只要一启动开火,就会产生大量的视频数据,一运行,就会产生很多的gps数据上传到数据中心,可以通过系统实时查看车上的视频情况和运行轨迹),被央视广泛宣传推广。数据量不是一般的多!!!视频数据还好,一会月没有盗窃案件事件就删除了(那时没有大数据的理念,也没有用人工智能训练数据的初衷,并没有存下来,且存储和内存还是很贵的,不像现在服务器几十上百G内存、存储空间以T为单位),可每辆车每天的gps数据却是长久保存的,要是哪天想回看在地图上的历史轨迹,就要从很多数据里检索,有点像后来衍生出的ofo、摩拜、滴滴和其他共享车平台。
附代码已上传github: https://github.com/dongguangming/golang-learn/tree/master/go-mongodb
参考:
The myth of NoSQL (vs. RDBMS) “joins dont scale”
How To Install MongoDB on CentOS 7 https://www.digitalocean.com/community/tutorials/how-to-install-mongodb-on-centos-7
mongodb设置密码 https://cloud.tencent.com/developer/article/1401326
MongoDB Configuration File Options https://docs.mongodb.com/manual/reference/configuration-options/#security-options
The
mongo
Shell https://docs.mongodb.com/manual/mongo/- How To Build Microservice With MongoDB In Golang https://goinbigdata.com/how-to-build-microservice-with-mongodb-in-golang/
How to paginate with MongoDB https://rabbitoncode.com/big-data/2019/10/11/pagination-mongo/
API Paging Built The Right Way https://engineering.mixmax.com/blog/api-paging-built-the-right-way/
Golang, Gin & MongoDB – Building microservices easily https://blog.codecentric.de/en/2020/04/golang-gin-mongodb-building-microservices-easily/
Paging with the Bucket Pattern - Part 1 https://www.mongodb.com/blog/post/paging-with-the-bucket-pattern--part-1
海量数据的分页怎么破 https://mongoing.com/archives/25469
Pagination for MSSQL & MongoDB https://piotrgankiewicz.com/2016/04/19/pagination-for-mssql-mongodb/
Working with MongoDB Using Golang https://levelup.gitconnected.com/working-with-mongodb-using-golang-754ead0c10c
Golang学习系列第六天:操作MongoDB相关推荐
- MongoDB学习系列9:MongoDB里的若干规则
2019独角兽企业重金招聘Python工程师标准>>> 数据库名字:规则 不能是空字符串 不得含有'' . $ / \ \0 应该全部小写 最多64字节. ~~~ admin数据 ...
- HIVE学习系列——Hive操作
文章目录 Hive表介绍 基本句法-创建新表: Demo运行(以实际使用中的常用句法为编写规范): Q&A 基本句法-向table添加数据 Demo运行(承接创建的表) Q&A 基本句 ...
- MongoDB学习系列 -- 数据库、集合、文档的CURD
前面一篇章节我们已经对MongoDB的基本概念有了一个大概的了解,从今天开始,我们将进行更细粒度的学习,首先就是数据库.集合.文档的CURD操作. 为了便于操作,减少学习难度,我们这里使用javasc ...
- golang常用库之-mgo.v2包、MongoDB官方go-mongo-driver包、七牛Qmgo包 | go操作mongodb、mongodb bson
文章目录 golang常用库之-mgo.v2包.MongoDB官方go-mongo-driver包.七牛Qmgo包 | go操作mongodb.mongodb bson 一.[不推荐]mgo.v2包 ...
- 使用Golang驱动操作MongoDB
微信公众号:运维开发故事,作者:wanger 上篇文章我们介绍了使用pymongo对MongoDB进行CRUD,本篇将介绍使用Golang驱动操作MongoDB 安装MongoDB驱动程序 mkdr ...
- Python学习系列(五)(文件操作及其字典)
Python学习系列(五)(文件操作及其字典) Python学习系列(四)(列表及其函数) 一.文件操作 1,读文件 在以'r'读模式打开文件以后可以调用read函数一次性将文件内容全部读出 ...
- 二、mongodb数据库系列——聚合操作 索引操作 权限管理
一.mongodb的聚合操作 学习目标 了解 mongodb的聚合原理 掌握 mongdb的管道命令 掌握 mongdb的表达式 1 mongodb的聚合是什么 聚合(aggregate)是基于数据处 ...
- python操作redis set_Python操作redis学习系列之(集合)set,redis set详解 (六)
#-*- coding: utf-8 -*- importredis r= redis.Redis(host="126.56.74.190",port=639,password=& ...
- PHP操作MongoDB学习笔记
PHP操作MongoDB技術總結 <?php /** * PHP操作MongoDB学习笔记 */ //************************* //** 连接MongoDB数据库 ...
最新文章
- 如何将一个列表当作元组的一个元素
- 微服务实践分享(4)配置中心
- PHP通过PDO连接Microsoft Access数据库
- linux 内核编译需要多大空间,编译2.6.28内核出错。。。。空间不足。而/tmp/还有好几G...
- 这些年Android面试的那些套路,社招面试心得
- 颜宁问4对科研夫妻:男女搭配,如何不累?
- 【报告分享】2019年中国数字经济发展指数.pdf(附下载链接)
- 网页下载CAB文件总结
- 统计信号处理基础-估计与检测理论的学习过程
- Acme CAD ConverterDWG文件查看器 2021
- java菜鸟疑问1:为什么我的代码总出现cannot be resolved or is not a field这种问题
- 金蝶K3修改库存更新控制方式
- editor上传视频无法播放的问题
- 商务办公软件应用与实践【8】
- 田老师书法工作室学员作品展(二)
- 京东管培生(产品方向)线上hr面
- 用数组实现求平均数小案例
- 星际争霸游戏战队案例分析
- App在appstore下架的方法
- 大学四年,我是如何学习编程的?