NoSQL查询相关

概要

  • 文档操作补充

  • 用户权限管理

  • 查询关键字

  • 分组与聚合

 


详情

    同步: 提交完任务之后原地等待任务的返回结果。
    异步: 提交完任务之后不原地等待任务的返回结果 结果通过回调获取。
  • 文档操作补充

# 数据的嵌套查找  有的值在字典内部嵌套的字典内
    .键名/索引名
    db.t1.deleteOne({'addr.counytry':'Japan'})
    db.t1.deleteOne({'hobby.1':'tea'})

  •  用户权限管理

1、用户权限相关语句,引号推荐使用双引号。

2、MongoDB针对用户权限的创建,数据可以保存在不同的数据库下,在登录的时候需要自己指定账户来源于哪个数据库。

3、管理员用户数据一般推荐保存到admin库下,而普通用户任意库都可以,为了便于管理可以在其它的一个库下创建普通用户。

# 创建管理员用户
1.切换到admin 
    use admin
2.创建管理员账户并赋予权限
    db.createUser(
        {
            user:"root",
            pwd:"123",
            roles:[{role:"root",db:"admin"}]
        }
    )
# 创建普通用户
1.切换到test库
    use test
2.创建普通用户账户并赋予权限
    db.createUser(
        {
            user:"Leoric",
            pwd:"12345",
            roles:[{role:"readWrite",db:"test"},
                   {role:"read",db:"db1"}]
        }
    )
# 使用管理员权限打开命令行窗口执行下列命令
1.停止当前服务
    net stop MongoDB
2.移除当前服务
    MongoD --remove
3.添加校验账户权限的MongoDB服务
    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
4.启动MongoDB服务
    net start MongoDB
# 验证方式
1.登录
mongo -u "root" -p "123" --port 27017 --authenticationDatabase "admin"
2.进入后验证
        mongo
        use admin
        db.auth("root","123")
""" 一般企业所有的数据库等都会有权限管理 """


  •  查询关键字

数据准备

# 数据的主键值 
    不指定会默认创建,指定则使用指定的值
# 插入单条
user0={
    "name":"jason",
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'BJ'
    }
}
db.user.insert(user0)
# 插入多条
user1={
    "_id":1,
    "name":"ax",
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'weifang'
    }
}
user2={
    "_id":2,
    "name":"wi",
    "age":20,
    'hobbies':['music','read','run'],
    'addr':{
        'country':'China',
        'city':'hebei'
    }
}
user3={
    "_id":3,
    "name":"yo",
    "age":30,
    'hobbies':['music','drink'],
    'addr':{
        'country':'China',
        'city':'heibei'
    }
}
user4={
    "_id":4,
    "name":"jg",
    "age":40,
    'hobbies':['music','read','dancing','tea'],
    'addr':{
        'country':'China',
        'city':'BJ'
    }
}
user5={
    "_id":5,
    "name":"jn",
    "age":50,
    'hobbies':['music','read',],
    'addr':{
        'country':'China',
        'city':'henan'
    }
}
db.user.insertMany([user1,user2,user3,user4,user5])
"""
    NoSQL学习诀窍
        可以先写SQL语句,根据SQL对比拼接出NoSQL语句。
"""

查询指定字段

# SQL写法
select name,age from db1.user where id=3;
# NoSQL写法
db.user.find(
    {'_id':3},
    {'_id':0,'name':1,'age':1}
)
''' 字段展示 '''
1.主键字段默认展示
2.普通字段键不写则不展示;值为1展示,值为0不展示

比较运算符

# SQL比较运算符: =,!=,>,<,>=,<=
# MongoDB以键值对的形式代表比较运算符  {key:value}
对应关系(等于关系不需要额外关键字)
键      符号
'$ne'    !=
'$gt'    >
'$lt'    <
'$gte'    >=
'$lte'    <=

1.select * from db1.user where name = "jason";
db.user.find({'name':'jason'})
2.select * from db1.user where name != "jason";
db.user.find({'name':{"$ne":'jason'}})
3.select * from db1.user where id > 2;
db.user.find({'_id':{'$gt':2}})
4.select * from db1.user where id < 3;
db.user.find({'_id':{'$lt':3}})
5.select * from db1.user where id >= 2;
db.user.find({"_id":{"$gte":2,}})
6.select * from db1.user where id <= 2;
db.user.find({"_id":{"$lte":2}})

逻辑运算符

# SQL逻辑运算符: and,or,not 
# MongoDB逻辑运算符
and 字典中以逗号分隔的多个条件
or'$or'为键的键值对,值为放在[]内以逗号分割的条件字典
not'$not'为键的键值对,值为条件字典

1.select * from db1.user where id >= 2 and id < 4;
db.user.find({'_id':{"$gte":2,"$lt":4}})
2.select * from db1.user where id >= 2 and age < 40;
db.user.find({"_id":{"$gte":2},"age":{"$lt":40}})
3.select * from db1.user where id >= 5 or name = "ax";
db.user.find({
    "$or":[
        {'_id':{"$gte":5}},
        {"name":"ax"}
        ]
})
4.select * from db1.user where id % 2=1;
db.user.find({'_id':{"$mod":[2,1]}})
5.上述语句取反
db.user.find({'_id':{"$not":{"$mod":[2,1]}}})

成员运算

# SQL成员运算: in,not in
# MongoDB成员运算:"$in","$nin"
1.select * from db1.user where age in (20,30,31);
db.user.find({"age":{"$in":[20,30,31]}})
2.select * from db1.user where name not in ('ax','yo');
db.user.find({"name":{"$nin":['ax','yo']}})
3.select * from db1.user where age in (20,30,31) or name!='jason';
db.user.find({
    '$or':[
        {'age':{'$in':[20,30,31]}},
        {'name':{'$ne':'jason'}}
    ]
})

正则表达式匹配

# SQL匹配正则关键字: regexp
# MongoDB匹配正则: /正则表达/i
1.select * from db1.user where name regexp '^j.*?(g|n)$';
db.user.find({'name':/^j.*?(g|n)$/i})

范围/模糊查询

# MySQL范围/模糊查询关键字: like
    关键符号
        %    匹配任意个数的任意字符
        _   匹配单个个数的任意字符
# MongoDB范围/模糊查询:
    以$all为键的键值对,值是条件范围列表,可以通过索引(句点符)或切片($slice)取值
# .find({查询条件},{筛选字段})方法默认范围查询
1.查看有dancing爱好的人
db.user.find({'hobbies':'dancing'})
2.查看既有dancing爱好又有tea爱好的人
db.user.find({
    'hobbies':{
        "$all":['dancing','tea']
        }
})
3.查看第4个爱好为tea的人
db.user.find({"hobbies.3":'tea'})
4.查看所有人最后两个爱好
db.user.find({},{'_id':0,'name':1,'hobbies':{"$slice":-2}})
5.查看所有人前面两个爱好
db.user.find({},{'_id':0,'name':1,'hobbies':{"$slice":2}})
6.查看所有人中间的第2个到第3个爱好
db.user.find({},{"_id":0,"name":1,'hobbies':{"$slice":[1,2]}})

排序

# MySQL排序关键字: order by
顺序
升序 asc
降序 desc
# MongoDB排序: .sort()
括号内存放排序字段与顺序组成的键值对{字段:顺序}
-1为降序、1为升序
1.select * from db.user order by age asc;
db.user.find().sort({"age":1})
2.select * from db.user order by age desc,_id asc
db.user.find().sort({"age":-1,'_id':1})
"""自动生成的主键一般大于手动指定的主键"""

 分页(限制查询结果数)

# MySQL分页关键字: limit 参数1,参数2
参数1为起始位置,参数2为数量
# MongoDB分页: .limit(参数1).skip(参数2)
参数1为展示document数,参数2为跳过document数
1.select * from db.user limit 2,1
db.user.find().sort({'age':1}).limit(1).skip(2)

补充

# 计数
db.user.count({'age':{"$gt":30}})
或者
db.user.find({'age':{"$gt":30}}).count()

# 空值匹配
1、{'key':null} 匹配key的值为null或者没有这个key的数据
db.t2.insert({'a':10,'b':111})
db.t2.insert({'a':20})
db.t2.insert({'b':null})
db.t2.find({"b":null})
# 查找所有
db.user.find() 等价于 db.user.find({})
# 查找单条,与find类似,只取查询结果的第一条
db.user.findOne({"_id":{"$gt":3}})


  • 分组与聚合

数据准备

在PyCharm中执行下列代码

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)
View Code

分组查询

# MongoDB分组:{'$group':{'_id':'$字段名'}
1.按照部门分组
db.emp.aggregate({'$group':{'_id':'$post'}})
2.按照年龄分组
db.emp.aggregate({'$group':{'_id':'$age'}})
3.求每个部门的平均年龄
db.emp.aggregate({
'$group':{
'_id':'$post',
'平均年龄':{'$avg':'$age'}
}
})
4.求每个部门的最高薪资与最低薪资
db.emp.aggregate({
'$group':{
'_id':'$post',
'最高薪资':{'$max':'$salary'},
'最低薪资':{'$min':'$salary'}
}
})
5.查询岗位名以及各岗位内的员工姓名
db.emp.aggregate({
"$group":{"_id":"$post","names":{"$push":"$name"}}
})
'''
  $match在$group之前等价于SQL中的where,在$group之后等价于SQL中的having
'''
6.查找主键值大于3的员工并按部门分组
db.emp.aggregate(
{"$match":{"_id":{"$gt":3}}},
{"$group":{"_id":"$post"}}
)
7.查找主键值大于三的员工并按部门分组在筛选出平均薪资大于10000的
db.emp.aggregate(
{"$match":{"_id":{"$gt":3}}},
{"$group":{"_id":"$post",'avg_salary': {"$avg":"$salary"}}},
{"$match":{"avg_salary":{"$gt":10000}}}
)


作业

1. 查询岗位名以及各岗位内的员工姓名
select post,group_concat(name) from emp group by post;

db.emp.aggregate({
    '$group':{
        '_id':'$post',
        'names':{'$push':'$name'}
    }
})
2. 查询岗位名以及各岗位内包含的员工个数
select post,count(id) from emp group by post;

db.emp.aggregate({
    '$group':{
        '_id':'$post',
        '$count':{'$sum':1}
    }
})
3. 查询公司内男员工和女员工的个数
select gender,count(id) from emp group by gender;

db.emp.aggregate({
    '$group':{
        '_id':'$gender',
        '$count':{'$sum':1}
    }
})
4. 查询岗位名以及各岗位的平均薪资、最高薪资、最低薪资
select post,avg(salary),max(salary),min(salary) from emp group by post;

db.emp.aggregate({
    '$group':{
        '_id':'$post',
        '平均薪资':{'$avg':'$salary'},
        '最高薪资':{'$max':'$salary'},
        '最低薪资':{'$min':'$salary'}
    }
})
5. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
select gender,avg(salary) from emp group by gender;

db.emp.aggregate({
    '$group':{
        '_id':'$gender',
        '$avg':'$salary'
    }
})
6. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
select post,group_concat(name),count(id) from emp 
group by post 
having count(id)<2;

db.emp.aggregate({'$group':{
                    '_id':'$post',
                    'names':{'$push':'$name'},
                    'num':{'$count':{'$sum':1}}}},
                {'$match':{'num':{'$lt':2}}})
7. 查询各岗位平均薪资大于10000的岗位名、平均工资
select post,avg(salary) from emp 
group by post 
having avg(salary)>10000;

db.emp.aggregate(
    {'$group':{'_id':'$post',
               'ayg_salary':{'$avg':'$salary'}
              }},
    {'$match':{'avg_salary':{'$gt':10000}}}
)
8. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均薪资
select post,avg(salary) from emp 
group by post 
having avg(salary)>10000 and avg(salary)<20000;

db.emp.aggregate(
    {'$group':{'_id':'$post',
               'avg_salary':{'$avg':'$salary'}
              }},
    {'$match':{'avg_salary':{'$gt':10000,'$lt':20000}}}
)
9. 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序
select * from emp order by age asc,hire_date desc;

db.emp.find().sort({'age':1,'hire_date':-1})
10. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列
select post,avg(salary) from emp group by post having avg(salary)>10000 order by avg(salary) asc;

db.emp.aggregate(
    {'$group':{'_id':'$post',
               'avg_salary':{'$avg':'$salary'}
              }},
    {'$match':{'avg_salary':{'$gt':10000}}}
).sort({'avg_salary':1})

11. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列,取前1个
select post,avg(salary) from emp 
group by post 
having avg(salary)>10000 
order by avg(salary) desc limit 1;

db.emp.aggregate(
    {'$group':{'_id':'$post',
               'avg_salary':{'$avg':'$salary'}
              }},
    {'$match':{'avg_salary':{'$gt':10000}}}
).sort({'avg_salary':-1}).limit(1).skip(0)

 

posted @ 2021-10-10 16:21  Leguan001  阅读(244)  评论(0)    收藏  举报