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的补充操作,用户权限管理,查询操作的主要内容,如果未能解决你的问题,请参考以下文章

mongodb 权限操作

14-补充内容:MySQl创建用户和授权

14-补充内容:MySQl创建用户和授权

MongoDB权限控制

mongodb权限管理(转)

Mongodb用户权限管理配置