文章目录
- 一、MongoDB介绍
- mongoDB相关概念
- 二、安装MongoDB
- 自动教程
- 三、shell模式下MongoDB基本命令
- 文档的增删改查
- 插入文档
- 查寻
- 更新文档
- 删除文档
- 其他常用命令
- 索引
- Golang操作MongoDB
- 简单连接栗子
- BSON简介
- 大文件读写
- 尾语
环境 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 })
插入多条文档
//insert 和 insertMany 都可以
//> db.user.insertMany([{name:"wyh",age:22},{name:"zjd",age:22}])
> 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.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:123@192.168.10.127: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副本集配置参考文档:
关于mongodb分片集配置参考文档:
未完待续…