设置访问权限
mongodb默认是无任何权限限制就能访问数据库,创建/修改数据库。
在默认启动文件mongodb.conf文件中有#auth=true,默认是关闭的,将该配置打开。重新启动mongodb服务。
# Turn on/off security. Off is currently the default
#noauth = true
auth = true
创建用户
创建管理员
安装mongodb后,默认不存在该数据库,需要创建admin库
1.创建admin数据库
use admin
2.添加管理员用户,身份roles是root,该身份拥有最高权限,可操作所有库。
db.createUser({user:"admin",pwd:"123456",roles:["root"]})
创建使用数据库的普通用户
1.切换数据库
use test
2.创建用户
db.createUser({user: "root", pwd: "123456", roles: [{ role: "dbOwner", db: "test" }]})
管理员和用户的区别,在创建时设置role角色的身份不同。
角色role是授予User在指定资源上执行指定操作的权限,MongoDB官方手册对角色的定义是:
MongoDB为了方便管理员管理权限,在DB级别上预先定义了内置角色;如果用户需要对权限进行更为细致的管理,MongoDB允许用户创建自定义的角色,能够在集合级别上控制User能够执行的操作。
MongoDB使用角色(Role)授予User访问资源的权限,Role决定User能够访问的数据库资源和执行的操作。一个User能够被授予一个或多个Role,如果User没有被授予Role,那么就没有访问MongoDB系统的权限。
内置角色是MongoDB预定义的角色,操作的资源是在DB级别上。MongoDB拥有一个SuperUser的角色:
root,只在admin数据库中可用。拥有最大权限,能够在系统的所有资源上执行任意操作。
数据库用户角色(Database User Roles):
- read:授予User只读数据的权限
- readWrite:授予User读写数据的权限
数据库管理角色(Database Administration Roles):
- dbAdmin:在当前dB中执行管理操作
- dbOwner:在当前DB中执行任意操作
- userAdmin:在当前DB中管理User
备份和还原角色(Backup and Restoration Roles):
- backup
- restore
跨库角色(All-Database Roles):
- readAnyDatabase:授予在所有数据库上读取数据的权限
- readWriteAnyDatabase:授予在所有数据库上读写数据的权限
- userAdminAnyDatabase:授予在所有数据库上管理User的权限
- dbAdminAnyDatabase:授予管理所有数据库的权限
认证用户
创建用户后,可以使用auth进行用户校验认证
db.auth(“admin”,”123456”)
db.auth(“root”,”123456”)
返回值为1则是被认证的身份,返回0则无权限访问。
在admin下创建的账户,不能直接在admin库上验证。必须切换到对应的数据库认证
// admin的库中创建test用户,test用户只可操作test数据库,认证要在创建的库admin中认证
db.createUser(
{
user:"test",
pwd:"123456",
roles:[{role:"readWrite",db:"test"}]
}
)
// 在test库中创建root用户,如果在admin库中认证,报错
db.auth("root","123456")
Error: Authentication failed.
0
查看数据库中所有用户
// 查看所有的用户我们必须在admin数据库下,在其他的数据中是查看不到的。
use admin
db.system.users.find().pretty()
删除用户
//删除某个用户,接受字符串参数
db.dropUser(<user_name>)
//示例:在test库中创建test2用户
use test
db.createUser({user:"test2",pwd:"123456",roles:[{role:"readWrite",db:"test"}]})
db.dropUser("test2")
//删除当前库的所有用户
db.dropAllUser()
⚠️总结:mongo数据库和别的数据库认证过程是不一样的,我们无需退出客户端便可以自动切换用户,来实现对不同数据库的操作。mongo中,在哪个数据库下创建的用户,就在哪个数据库下开启认证,也就是说,在A数据库创建的用户user1,只能在数据库A下面开启认证,在B数据库下面认证user1是不能成功的,在B数据库下只能认证user2数据库。数据库账户是跟着数据库走的。
用户role和数据库基于角色的权限控制
mongodb数据库操作
1:创建数据库
use testlib
要添加数据后,show dbs才会显示在数据库列表中。
2:创建集合collection
创建好数据库,要想添加数据必须先创建集合,集合类似sql数据库中表的概念。创建一个水果表。
db.createCollection(“fruit”)
然后show collections可以查看该数据库下的所有集合。
删除集合:db.collectionName.drop();
db.createCollection("fruit123")
show collections
db.fruit123.drop()
3:插入数据
文档的数据结构和JSON基本一样。
所有存储在集合中的数据都是BSON格式。
BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。
MongoDB 使用 insert() 或 save() 方法向集合中插入文档。
语法:db.collectionName.insert({})或db.collectionName.save({})
db.fruit.insert({name:'apple',"num":12})
db.fruit.save({name:'banana',"num":7})
db.fruit.find()
4:修改数据
MongoDB 使用 update() 和 save() 方法来更新集合中数据
update方法语法:
db.collectionName.update(
参数说明:
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
save方法语法:
db.collection.save(
参数说明:
- document : 文档数据。
writeConcern :可选,抛出异常的级别。
db.fruit.update({name:"apple"},{name:"apple",'num':123})
//如果使用save修改,必须通过ObjectId查询并修改,如果不传ObjectId参数,那么就会新创建一条数据
db.fruit.save({ "_id" : ObjectId("60ed576cf0e4913b69faabb9"), "name" : "orange", "num" : 22 })
//新增了一条数据
db.fruit.save({ "name" : "orange", "num" : 12322 })
5:删除数据
remove()函数是用来移除集合中的数据
语法:db.collection.remove(, { justOne: , writeConcern: } )
默认会删除查询结果的所有数据,如果只删除一条,需要设置删除条件db.fruit.remove({"name" : "orange", "num" : 20})
// 只删除一条查询出来的数据
db.fruit.remove({"num" : 20}, 1)
删除集合下的所有数据
db.fruit.remove({})
6:查询数据
使用find()函数进行查询数据。
语法:db.collectionName.find(query, projection);query :可选,使用查询操作符指定查询条件
- projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略),包含两种模式inclusion【包含】和exclusion【排除】
使用 pretty() 方法以易读的方式来读取数据,语法: db.collectionName.find().pretty();
显示指定列
db.collection.find(query, {name: 1, num: 1}) // inclusion模式,设置为1, 指定返回的键,不返回其他键,查询出的数据只显示指定字段。
db.collection.find(query, {id: 0}) // exclusion模式,设置为0,不返回的键。_
> db.fruit.find({name:'apple'},{num:1})
{ "_id" : ObjectId("60ed5754f0e4913b69faabb8"), "num" : 123 }
> db.fruit.find({name:'apple'},{num:1,_id:0})
{ "num" : 123 }
⚠️:如果设置了exclusion模式,另外设置查询值除了_id特殊,其他字段必须是一致的,如:name:1,num:1;或者name:0,num:0; 不可设置为name:1,num:0;这样会出现语法错误
7:通过条件查询where/like/and/or
where查询
等于 | { |
db.col.find({“by”:”abc”}).pretty() | where by = ‘abc’ |
---|---|---|---|
小于 | { |
db.col.find({“likes”:{$lt:50}}).pretty() | where likes < 50 |
小于或等于 | { |
db.col.find({“likes”:{$lte:50}}).pretty() | where likes <= 50 |
大于 | { |
db.col.find({“likes”:{$gt:50}}).pretty() | where likes > 50 |
大于或等于 | { |
db.col.find({“likes”:{$gte:50}}).pretty() | where likes >= 50 |
不等于 | { |
db.col.find({“likes”:{$ne:50}}).pretty() | where likes != 50 |
db.fruit.find({"name":"apple"}).pretty()
db.fruit.find({"num":{$lt:20}}).pretty()
db.fruit.find({"num":{$gt:30}}).pretty()
and条件
find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件
语法格式如下:db.collectionName.find({key1:value1, key2:value2}).pretty()
db.fruit.find({name:'peach',num:22}).pretty()
OR 条件
语法格式如下:db.collectionName.find({$or: [ {key1: value1}, {key2:value2} ] } ).pretty()
db.fruit.find({$or:[{name:'peach'},{num:22}]}).pretty()
db.fruit.find({$or:[{name:'peach'},{name:'apple'}]}).pretty()
AND 和 OR 联合使用
db.fruit.find({ 'num':{$lt:30}, $or:[{name:'peach'}] }).pretty()
8:limit/skip/sort 查询
limit查询
在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
语法:db.collectionName.find().limit(NUMBER)
db.fruit.find().limit(3)
skip查询
使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
语法:db.collectionName.find().limit(NUMBER).skip(NUMBER)
db.fruit.find().limit(3).skip(2)
sort查询
使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
语法: db.collectionName.find().sort({KEY:1})
db.fruit.find().limit(3).skip(2)
⚠️注:skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()。
设置多IP模式
在/etc/mongod.conf中,有bind_ip字段,可以绑定固定的IP地址,如果在服务器内部访问,直接使用localhost或127.0.0.1即可,但是有其它服务器要访问远程服务器上的数据库,需要把ip设置为服务器的内网ip,可以用ifconfig查看内网ip
在mongo 3.2.7中的括号对ip进行包装
// 3.2.7
bindIp = [127.0.0.1, 192.168.184.155, 96.88.169.145]
但是我使用了3.6.3版本,以上方案不行。
mongod -version
db version v3.6.3
// 在3.6.3版本中,使用bind_ip放多个ip地址用逗号分隔,可以设置为
bind_ip : 127.0.0.1,172.18.241.21
// 或者开启bind_ip_all属性,不限制ip
bind_ip_all : true
启动或关闭mongodb服务
- 启动服务 sudo systemctl start mongodb或者sudo service mongodb start
- 关闭服务 sudo systemctl stop mongodb或者sudo service mongodb stop
如果ubuntu版本老,需要把systemctl换成service
查看mongodb服务状态,可以通过27017端口查看
netstat -lanp | grep "27017"
如果显示两个ip都为listen状态,表示启动成功
使用mongo访问数据库
可以在服务端查看访问数据库
mongo 172.18.241.21:27017 或者 mongo 127.0.0.1:27017
# 连接数据库
mongoose.connect('mongodb://test:123456@88.888.88.888:27017/test?authSource=admin', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('数据库连接成功'))
.catch(() => console.log('数据库连接失败'))
# 参数说明
# testadmin 用户名称
# testadmin123 用户密码
# 88.888.88.888 服务器地址
# 27017 端口号码
# testmongodb 连接的数据库
# ?authSource=admin 权限来源
# 至此,可以通过 mongoose 连接数据库
安装和卸载
安装
// 安装
sudo apt-get install mongodb
// 运行
sudo service mongodb start
// 使用命令启动mongo
mongo
// 使用验证启动,验证登录的用户不能是admin数据库
mongo -u "test" -p "123456" "test"
卸载
先停止运行mongodb
sudo service mongodb stop
删除
sudo apt-get purge mongodb
sudo apt-get remove —auto-remove mongodb
删除数据库和日志文件
sudo rm -r /var/log/mongodb
sudo rm -r /var/lib/mongodb