爬虫学习笔记10-MongoDB聚合、索引、权限管理以及与Python交互

1、mongodb的聚合操作

①聚合: 每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
语法:db.集合名称.aggregate({管道:{表达式}})
②常用管道命令:
语法: {管道:{表达式}}

  • $group: 将集合中的⽂档分组, 可⽤于统计结果
  • $match: 过滤数据, 只输出符合条件的⽂档
  • $project: 修改输⼊⽂档的结构, 如重命名、 增加、 删除字段、 创建计算结果
  • $sort: 将输⼊⽂档排序后输出
  • $limit: 限制聚合管道返回的⽂档数
  • $skip: 跳过指定数量的⽂档, 并返回余下的⽂档

③常⽤表达式:
语法:表达式:'$列名'

  • $sum: 计算总和, $sum:1 表示以⼀倍计数
  • $avg: 计算平均值
  • $min: 获取最⼩值
  • $max: 获取最⼤值
  • $push: 在结果⽂档中插⼊值到⼀个数组中

(1)group分组管道:用来将集合中的文档分组,可用于统计结果

db.stu.aggregate({$group:
        {
            _id:"$gender",
            counter:{$sum:1}
        }
    }
)

其中注意点:

  • db.db_name.aggregate是语法,所有的管道命令都需要写在其中
  • _id 表示分组的依据,按照哪个字段进行分组,需要使用$gender表示选择这个字段进行分组
  • $sum:1 表示把每条数据作为1进行统计,统计的是该分组下面数据的条数
db.stu.aggregate(
    {$group:
        {
            _id:null,
            counter:{$sum:1}
        }
    }
)

其中注意点:

  • _id:null 表示不指定分组的字段,即统计整个文档,此时获取的counter表示整个文档的个数

案例操作:
①统计不同性别的人数

db.stu.aggregate({$group:
{
	_id:"$gender",
	counter:{$sum:1}
}
})

在这里插入图片描述
②统计不同性别的年龄总和

db.stu.aggregate({$group:
{
	_id:"$gender",
	age_counter:{$sum:"$age"}
}
})

在这里插入图片描述
③统计不同性别的平均年龄

db.stu.aggregate({$group:
{
	_id:"$gender",
	avg_age:{$avg:"$age"}
}
})

在这里插入图片描述
④罗列出不同性别的人的名字

db.stu.aggregate({$group:
{
	_id:"$gender",
	name_list:{$push:"$name"}
}
})

在这里插入图片描述

(2)match过滤管道: 过滤数据, 只输出符合条件的⽂档
match和find的区别: $match 操作可以把结果交给下一个管道处理,而find不行。
案例操作
①过滤年龄为18的成员

db.stu.aggregate({$match:
{
	age:18
}
})

在这里插入图片描述

②过滤年龄为18的成员并按性别分成两组,同时把成员姓名罗列出来

db.stu.aggregate(
	{$match:{age:18}},
	{$group:{
		_id:"$gender",
		name_list:{$push:"$name"}
		}
	}
)

在这里插入图片描述
(3)project投影管道:用于修改文档的输入输出结构,例如重命名,增加,删除字段
案例操作:
①仅输出成员的姓名和年龄

db.stu.aggregate(
	{$project:{
		_id:0,
		name:1,
		age:1}
	}
)

在这里插入图片描述

②仅输出成员的姓名和年龄,同时重命名输出

db.stu.aggregate(
	{$project:{
		_id:0,
		"姓名":"$name",
		"年龄":"$age"
		}
	}
)

在这里插入图片描述
(4)sort排序管道:用于将输入的文档排序后输出
案例操作:
①查询成员信息,按照年龄升序

db.stu.aggregate(
	{$sort:
		{age:1}
	}
)

②通过性别分组,查询成员信息,按照人数降序

db.stu.aggregate(
	{$group:{
		_id:"$gender",
		counter:{$sum:1}
		}
	},
	{$sort:{
		counter:-1
		}
	}
)

在这里插入图片描述
(5)limit限制管道:限制输出的文档数;skip:跳过指定的文档数
案例操作:
先跳过3条文档,限制输出2条文档

db.stu.aggregate(
	{$skip:3},
	{$limit:2}
)

在这里插入图片描述

2、Mongodb的索引操作

**作用:**加快查询速度;进行数据的查重
键入测试数据:

for(i=0;i<100000;i++){
	db.t1.insert(
		{name:'test'+i,age:i}
		)
	}

在这里插入图片描述

(1)创建索引:db.集合名.ensureIndex({属性:1}),1表示升序, -1表示降序

db.t1.ensureIndex({name:1})

创建前后查找速度对比:

db.t1.find({name:'test10000'}).explain('executionStats') # 显示查询操作的详细信息
  • 创建索引前:
    在这里插入图片描述
    创建索引后:
    在这里插入图片描述

(2)查看索引:db.集合名.getIndexes()
在这里插入图片描述
(3)删除索引:db.集合名.dropIndex({'索引名称':1})
在这里插入图片描述
(4)创建唯一索引:db.集合名.ensureIndex({"字段名":1}, {"unique":true})
利用唯一索引可以进行数据去重,当创建了唯一索引以后相同的数据将无法插入
在这里插入图片描述
(5)建立复合索引:db.collection_name.ensureIndex({字段1:1,字段2:1})
在进行数据去重的时候,可能用一个域来保证数据的唯一性,这个时候可以考虑建立复合索引来实现。

建立索引需注意:

  • 根据需要选择是否需要建立唯一索引
  • 索引字段是升序还是降序在单个索引的情况下不影响查询效率,但是带复合索引的条件下会有影响
  • 数据量巨大并且数据库的读出操作非常频繁的时候才需要创建索引,如果写入操作非常频繁,创建索引会影响写入速度 例如:在进行查询的时候如果字段1需要升序的方式排序输出,字段2需要降序的方式排序输出,那么此时复合索引的建立需要把字段1设置为1,字段2设置为-1

3、Mongodb的权限管理

目的: 需要设置权限以保证公网运行系统数据安全
管理员: 超级管理员、普通用户

  • 用户只能在用户所在数据库登录(创建用户的数据库),包括管理员账号。
  • 管理员可以管理所有数据库,但是不能直接管理其他数据库,要先认证后才可以。

配置文件:

(1)创建超级管理员

  • 进入mongo shell:sudo mongod

  • 使用admin数据库(超级管理员账号必须创建在该数据库上):use admin

  • 创建超级用户:db.createUser({"user":"用户名","pwd":"密码","roles":["root"]})
    在这里插入图片描述

  • 退出(exit),以权限认证的方式启动mongodb数据库:sudo mongod --auth

  • 登录验证:

	use admin
	db.auth('用户名','密码')

注:

  • python用户是创建在admin数据库上的所以必须来到admin数据库上进行认证
  • 认证成功会返回1,失败返回0

(2)创建普通用户

  • 选择需要创建用户的数据库:use test1
  • 创建用户:
db.createUser("user":"user1", "pwd":"pwd1", roles:["read"])
创建普通用户user1,该用户在test1上的权限是只读
db.createUser("user":"user1", "pwd":"pwd1", roles:["readWrite"])
创建普通用户user1,该用户在test1上的权限是读写

(3)在admin用户数据库上创建普通用户

#在admin上创建python1用户,python1用户的权限有两个,一个再dbname1上的只读,另一个是在dbname2上的读写
use admin
db.createUser({"user":"python1", "pwd":"python1", roles:[{"role":"read","db":"dbname1"},{"role":"readWrite","db":"dbname2"}
]})

(4)查看已经创建的用户:show users
在这里插入图片描述
(5)删除用户

  • 进入账号数据所在的数据库:use 账号所在数据库名
  • 删除用户db.dropUser('用户名')

4、mongodb和python交互

pymongo官方文档或源代码
(1)安装交互模块:pip install pymongo
(2)使用pymongo模块
①无需权限认证的方式创建连接对象以及集合操作对象

from pymongo import MongoClient

client = MongoClient('host',port) # 如果是本地连接host,port参数可以省略

collection = client[db名][集合名]
# collection = client.db名.集合名 # 与上边用法相同

②需要权限认证的方式创建连接对象以及集合操作对象

from pymongo import MongoClient

client = MongoClient('host',port)

# collection = client['db名']['集合名']
# collection = client.db名.集合名 # 与上边用法相同
# 选择一个数据库
db = client['admin']
db.authenticate('用户名','用户密码')

# 选择一个集合
col = client['db名','集合名']

(3)数据的增删改查
①insert()添加数据

# 单条数据添加
collection.insert({一条数据})
# 批量添加数据
collection.insert([{数据一},{数据二}])

例:单条数据的添加

from pymongo import MongoClient

client = MongoClient()

collection = client['amen']['test1']
ret = collection.insert({"name":"哈登","team":"火箭队"})
print(ret)

在这里插入图片描述

在这里插入图片描述
例:多条数据的添加

from pymongo import MongoClient

client = MongoClient()

collection = client['amen']['test1']
collection.insert([{"name":"威少","team":"火箭队"},{"name":"詹姆斯","team":"湖人队"}])

在这里插入图片描述

②find()数据的查找

#单条数据的查找,返回一条数据
collection.findone()
#多条数据的查找,返回一个可迭代对象
collection.find()

例:单条数据的查找

from pymongo import MongoClient

client = MongoClient()
collection = client['amen']['test1']
ret = collection.find_one({"name":"哈登"})
print(ret)

在这里插入图片描述

例:多条数据的查找

from pymongo import MongoClient

client = MongoClient()
collection = client['amen']['test1']
rets = collection.find({"team":"火箭队"})
for ret in rets:
    print(ret)

在这里插入图片描述
③update()更新数据(全文档覆盖或指定键值,更新一条或多条)
语法:collection.update({条件}, {'$set':{指定的kv或完整的一条数据}}, multi=False/True, upsert=False/True)

  • $set表示指定字段进行更新
  • multi参数:默认为False,表示更新一条; multi=True则更新多条; multi参数必须和$set一起使用
  • upsert参数:默认为False; upsert=True则先查询是否存在,存在则更新;不存在就插入

案例1:更新一条数据;全文档覆盖;存在就更新,不存在就插入
在这里插入图片描述
案例2:更新多条数据;全文档覆盖;存在就更新,不存在就插入
在这里插入图片描述
案例3:更新一条数据;指定键值;存在就更新,不存在就插入
在这里插入图片描述
案例4:更新多条数据;指定键值;存在就更新,不存在就插入
在这里插入图片描述
④ delete()删除数据

# 删除一条数据
delete_one()
# 删除全部数据
delete_many()

案例1:删除一条数据
在这里插入图片描述
案例2:删除全部数据
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值