MongoDB的补充操作,用户权限管理,查询操作
Posted 微纯册
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB的补充操作,用户权限管理,查询操作相关的知识,希望对你有一定的参考价值。
MongoDB的补充操作,用户权限管理,查询操作
- 文档操作补充
- 用户权限管理
- 数据查询方法
文档操作补充
删除
\'\'\'涉及到数据的嵌套查找 支持直接点键或者索引\'\'\'
eg:
db.db1.find({\'ddd.fg\':123})
db.db1.find({\'fgh.0\':\'iii\'})
用户权限管理
"""涉及到用户权限相关 引号推荐全部使用双引号"""
创建用户
\'\'\' mongodb针对用户权限的创建,数据可以保存在不同的数据库下 之后在登录的时候只需要自己指定账户数据来源于哪个数据库即可 管理员用户数据一般情况下推荐保存到admin库下 而普通用户任意库都可以 \'\'\'
创建管理员
1.切换到admin数据库下
use admin
2.创建账户并且赋予权限
# 用户名为:root
# 密码:123
# 权限:管理员,存储位置:admin库
db.createUser({ user: "root", pwd: "123", roles: [ { role: "root", db: "admin" } ] })
其他用户在test数据库下创建
1.切换到test数据库下
use test
2.创建账户并赋予权限
针对test库用于读写的权限 针对db1库只拥有读的权限
db.createUser({ # 用户名:jason user: "jason", # 密码:123 pwd: "123", # 权限:读写,存储位置:test roles: [ { role: "readWrite", db: "test" }, # 权限:读 存储位置:db1 { role: "read", db: "db1" } ] })
为了使设置生效,要进行下部操作
停止服务
net stop MongoDB
再移除服务
MongoDB --remove
再次系统配置
mongod --bind_ip 0.0.0.0 --port 27017 --logpath D:\\MongoDB\\log\\mongod.log --logappend --dbpath D:\\MongoDB\\data --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install --auth
在此启动
net start MongoDB
两种验方式
1.直接登录验证
mongo -u "root" -p "123" --port 27017 --authemticationDatabase "admin"
2.进入之后再验证
>mongo >use admin >db.auth("root","123")
"""正规公司所有的数据库等都会有权限管理"""
数据查询方法
数据准备
\'\'\'是输出结果形式好看\'\'\' db.表名.find().pretty
查询指定字段
# 查找id为3的名字与年龄 db.user.find({\'_id\':3},{\'_id\':0,\'name\':1,\'age\':1})
\'\'\'0表示不要 1表示要\'\'\'
针对主键字段_id如果不指定默认是必拿的
普通字段不写就表示不拿
查询
学习mongodb的查询语句只要对比着mysql去学,非常的容易!
并且在书写mongodb查询语句的时候,我们可以先使用MySQL的SQL语句
然后参考SQL语句再书写mongodb语句(相当于将MySQL语句翻译成mongodb)
比较运算符
mongoDB符号 | 意义 |
$ne | != |
$gt | > |
$lt | < |
$gte | >= |
$lte | <= |
{key:value} | = |
查找name为jason的user信息
db.user.find({\'name\':\'jason\'})
查找name不为jason的user信息
db.user.find({\'name\':{\'$ne\':\'jason\'}})
查找id大于2的user信息
db.user.find({\'_id\':{\'$gt\':2}})
查找id小于3的user信息
db.user.find({\'_id\':{\'$lt\':3}})
查找id大于等于2的user信息
db.user.find({\'_id\':{\'$gte\':2}})
查找id小于等于2的user信息
db.user.find({"_id":{"$lte":2}})
逻辑运算符
在SQL中:and,or,not
NOSQL中:逗号分隔的多个条件是and关系
“$or”的条件放在[]中
“$not”取反
1.查找id大于2和id小于4的user信息
db.user.find({"_id":{"$gte":2,"$lt":4}})
2.查找id大于2和年龄小于40的user信息
db.user.find({"_id":{"$gte":2},"ago":{"$lt":40}})
# 没有符合要求信息输出为空
3.查找id大于5或者名字等于ax的user信息你
db.user.find({ "$or":[{ \'_id\':{"$gte":5}}, {"name":"ax"}]})
4.查找id整除2为1(即奇数)的user信息
db.user.find({\'_id\':{"$mod":[2,1]}})
5.上体取反
db.user.find({\'_id\':{"$not":{"$mod":[2,1]}}})
成员运算
在SQL中:in,not in 在NoSQL中:"$in","$nin"
查找age在20,30和31中的user信息
db.user.find({"age":{"$in":[20,30,31]}})
查看name不为ax和yo的user信息
db.user.find({"name":{"$nin":[\'ax\',\'yo\']}})
查看name不为jason或age在20,30和31中的user信息
db.user.find({\'$or\':[{\'age\':{\'$in\':[20,30,31]}},{\'name\':{\'$ne\':\'jason\'}}]})
正则匹配
用正则符号组合去文本中筛选出符合条件的数据
# SQL:regexp 正则
# MongoDB:/正则表达/i
使用正则获取name的j开头以g或n结尾的非贪婪匹配
db.user.find({\'name\':/^j.*?(g|n)$/i})
范围/模糊查询
语法: find({查询条件},{筛选字段}) """ MySQL 关键字 like 关键符号 % 匹配任意个数的任意字符 _ 匹配单个个数的任意字符 MongoDB: 通过句点符 $all """
查看有dancing爱好的人
# 默认就是范围查询 db.user.find({\'hobbies\':\'dancing\'})
查看既有dancing爱好又有tea爱好的人
db.user.find({\'hobbies\':{"$all":[\'dancing\',\'tea\']}})
查看第4个爱好为tea的人
db.user.find({"hobbies.3":\'tea\'})
查看所有人最后两个爱好
db.user.find({},{\'_id\':0,\'name\':1,\'hobbies\':{\'$slice\':-2}})
查看所有人前面两个爱好
db.user.find({},{\'_id\':0,\'name\':1,\'hobbies\':{"$slice":2}})
查看所有人中间的第2个到第3个爱好
db.user.find({},{"_id":0,"name":1,\'hobbies\':{"$slice":[1,2]}})
排序
""" MySQL: 关键字 order by 升序 降序 asc desc MongoDB 关键字 sort 升序 降序 1 -1 """
排序:1代表升序,-1代表降序
按照age升序排序
db.user.find().sort({"age":1})
按照age降序排列
db.user.find().sort({"age":-1,"_id":1})
""" MySQL 关键字 limit 分页 5,5 MongoDB 关键字 limit 分页 skip """
输出1项跳过2项
# 分页:limit代表取多少个document,skip代表跳过前多少个document
db.user.find().sort({\'age\':1}).limit(1).skip(2)
杂项补充
获取数量
eg:
获取age大于30的user信息
db.user.count({\'age\':{"$gt":30}})
# 输出为2
db.user.find({\'age\':{"$gt":30}}).count()
# 同上,输出为2
{\'key\':null} 匹配key的值为null或者没有这个key的数据
eg:
db.user.insert({\'a\':10,\'b\':null}) db.user.find({\'b\':null})
查找所有
# 等同于db.user.find({}) db.表名.find()
至查找一个
eg:
查一个id大于3的user信息
db.user.findOne({"_id":{"$gt":3}})
数据准备
from pymongo import MongoClient import datetime client=MongoClient(\'mongodb://root:123@localhost:27017\') table=client[\'db1\'][\'emp\'] # table.drop() l=[ (\'jason\',\'male\',18,\'20170301\',\'老男孩驻沙河办事处外交大使\',7300.33,401,1), #以下是教学部 (\'ax\',\'male\',78,\'20150302\',\'teacher\',1000000.31,401,1), (\'wxx\',\'male\',81,\'20130305\',\'teacher\',8300,401,1), (\'yh\',\'male\',73,\'20140701\',\'teacher\',3500,401,1), (\'lz\',\'male\',28,\'20121101\',\'teacher\',2100,401,1), (\'jly\',\'female\',18,\'20110211\',\'teacher\',9000,401,1), (\'jx\',\'male\',18,\'19000301\',\'teacher\',30000,401,1), (\'成龙\',\'male\',48,\'20101111\',\'teacher\',10000,401,1), (\'歪歪\',\'female\',48,\'20150311\',\'sale\',3000.13,402,2),#以下是销售部门 (\'丫丫\',\'female\',38,\'20101101\',\'sale\',2000.35,402,2), (\'丁丁\',\'female\',18,\'20110312\',\'sale\',1000.37,402,2), (\'星星\',\'female\',18,\'20160513\',\'sale\',3000.29,402,2), (\'格格\',\'female\',28,\'20170127\',\'sale\',4000.33,402,2), (\'张野\',\'male\',28,\'20160311\',\'operation\',10000.13,403,3), #以下是运营部门 (\'程咬金\',\'male\',18,\'19970312\',\'operation\',20000,403,3), (\'程咬银\',\'female\',18,\'20130311\',\'operation\',19000,403,3), (\'程咬铜\',\'male\',18,\'20150411\',\'operation\',18000,403,3), (\'程咬铁\',\'female\',18,\'20140512\',\'operation\',17000,403,3) ] for n,item in enumerate(l): d={ "_id":n, \'name\':item[0], \'sex\':item[1], \'age\':item[2], \'hire_date\':datetime.datetime.strptime(item[3],\'%Y%m%d\'), \'post\':item[4], \'salary\':item[5] } table.save(d)
分组查询
按照部门分组,输出部门名
db.emp.aggregate({\'$group\':{\'_id\':\'$post\'}})
求每个部门的平均年龄
db.emp.aggregate({"$group":{\'_id\':\'$post\',\'avgage\':{\'$avg\':\'$age\'}}})
求每个部门的最高薪资与最低薪资
db.emp.aggregate({ \'$group\':{ \'_id\':\'$post\', \'最高薪资\':{\'$max\':\'$salary\'}, \'最低薪资\':{\'$min\':\'$salary\'} } })
求id大于3每个部门的信息
db.emp.aggregate(
# 分组之前筛选数据 {"$match":{"_id":{"$gt":3}}}, {"$group":{"_id":"$post"}} )
求id大于3每个部门的信息的平均工资大于10000的信息
db.emp.aggregate( {"$match":{"_id":{"$gt":3}}}, # 出现在$group上面就是where {"$group":{"_id":"$post",\'avg_salary\':{"$avg":"$salary"}}}, {"$match":{"avg_salary":{"$gt":10000}}} # 出现在$group下面就是having )
1. 查询岗位名以及各岗位内的员工姓名
db.emp.find({},{"_id":0,"post":1,"name":1})
2. 查询岗位名以及各岗位内包含的员工个数
# SQL:select post,count(name) from emp group by post; db.emp.aggregate({"$group":{\'_id\':\'$post\',\'count\':{"$sum":1}}})
3. 查询公司内男员工和女员工的个数
db.emp.aggregate({"$group":{\'_id\':\'$sex\',\'count\':{"$sum":1}}})
4. 查询岗位名以及各岗位的平均薪资、最高薪资、最低薪资
db.emp.aggregate({ \'$group\':{ \'_id\':\'$post\', \'最高薪资\':{\'$max\':\'$salary\'}, \'平均工资\':{\'$avg\':\'$salary\'}, \'最低薪资\':{\'$min\':\'$salary\'} } })
5. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
db.emp.aggregate({"$group":{\'_id\':\'$sex\',\'count\':{"$avg":"$salary"}}})
6. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
# SQL:select post,group_concat(name),count(name) from emp group by post having count(name)>2
db.emp.aggregate(
{
"$group":{"_id":"$post","count":{"$sum":1},"names":{"$push":"$name"}}
},
{"$match":{"count":{"$lt":2}}},
{"$project":{"_id":0,"namestelnet your.machine.open.ip 27017
2. 启用验证
2.1 创建用户管理员账户
当前数据库版本:Mongodb 3.4
使用 mongod 启动数据库
新建终端
mongod --port 27017 --dbpath /data/db1
参数默认可以不加,若有自定义参数,才要加上,下同。
另起一个终端,运行下列命令
mongo --port 27017
use admin
db.createUser(
{
user: "adminUser",
pwd: "adminPass",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
管理员创建成功,现在拥有了用户管理员
用户名:adminUser
密码:adminPass
然后,断开 mongodb 连接, 关闭数据库
两个终端下 <C - c>
2.2 Mongodb 用户验证登陆
启动带访问控制的 Mongodb
新建终端
mongod --auth --port 27017 --dbpath /data/db1
现在有两种方式进行用户身份的验证
第一种 (类似 MySql)
客户端连接时,指定用户名,密码,db名称
mongo --port 27017 -u "adminUser" -p "adminPass" --authenticationDatabase "admin"
第二种
客户端连接后,再进行验证
mongo --port 27017
use admin
db.auth("adminUser", "adminPass")
// 输出 1 表示验证成功
2.3 创建普通用户
过程类似创建管理员账户,只是 role 有所不同
use foo
db.createUser(
{
user: "simpleUser",
pwd: "simplePass",
roles: [ { role: "readWrite", db: "foo" },
{ role: "read", db: "bar" } ]
}
)
现在我们有了一个普通用户
用户名:simpleUser
密码:simplePass
权限:读写数据库 foo, 只读数据库 bar。
注意
NOTE
WARN
use foo
表示用户在 foo 库中创建,就一定要 foo 库验证身份,即用户的信息跟随随数据库。比如上述 simpleUser 虽然有 bar 库的读取权限,但是一定要先在 foo 库进行身份验证,直接访问会提示验证失败。
use foo
db.auth("simpleUser", "simplePass")
use bar
show collections
还有一点需要注意,如果 admin 库没有任何用户的话,即使在其他数据库中创建了用户,启用身份验证,默认的连接方式依然会有超级权限
2.4 内建角色
- Read:允许用户读取指定数据库
- readWrite:允许用户读写指定数据库
- dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
- userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
- clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
- readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
- readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
- userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
- dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
- root:只在admin数据库中可用。超级账号,超级权限
2.5 URI 形式的访问
生产中常用 URI 形式对数据库进行连接
mongodb://your.db.ip.address:27017/foo
添加用户名密码验证
mongodb://simpleUser:[email protected]:27017/foo
以上是关于MongoDB的补充操作,用户权限管理,查询操作的主要内容,如果未能解决你的问题,请参考以下文章