Python全栈 MongoDB 数据库(聚合、二进制、GridFS、pymongo模块)

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:
断网了2天  今天补上


聚合操作:
对文档的信息进行 整理统计的操作
返回:统计后的文档集合
db.collection.aggregate()
功能:聚合函数,完成聚合操作
参数:聚合条件,配合聚合操作符使用
返回:聚合后的结果

常用聚合操作符:
1. $group  分组聚合   要配合具体的统计操作符获取结果

$sum  求和
db.class1.aggregate({$group:{_id:'$gender',num:{$sum:1}}})
     分组   按照gender值统计 统计结果,求和每有一个加1
统计所有男生和女生的年龄之和
db.class1.aggregate({$group:{_id:'$gender',num:{$sum:'$age'}}})
$avg  平均值
求男生 女生年龄的平均数
db.class1.aggregate({$group:{_id:'$gender',num:{$avg:'$age'}}})
$max 求最大值
求男生女生的年龄最大值
db.class1.aggregate({$group:{_id:'$gender',num:{$max:'$age'}}})
$min  求最小值
求男生女生的年龄最小值
db.class1.aggregate({$group:{_id:'$gender',num:{$min:'$age'}}})

2. $project
用于修改文档的显示效果

$project值的用法同find()的field参数相同
db.class1.aggregate({$project:{_id:0,name:1,age:1}})

自定义显示的域名
db.class1.aggregate({$project:{_id:0,Name:'$name',Age:'$age'}})


3. $match
过滤想要的数据

过滤年龄大于30的数据,$match值的写法同query
db.class1.aggregate({$match:{age:{$gt:30}}})

4. $limit
显示前几个文档
db.class1.aggregate({$limit:3})

5. $skip
跳过前几个文档显示
db.class1.aggregate({$skip:2})

6. $sort   排序

按照年龄排序
db.class1.aggregate({$sort:{age:1}})

聚合管道
将前一个聚合操作产生的结果,交给后一个聚合操作继续使用
db.collection.aggregate([{聚合1},{聚合2},{}...])

$match --> $sort -->$project
db.class1.aggregate([{$match:{gender:'m'}},{$sort:{age:1}},{$project:{_id:0}}])

聚合示例
使用grade数据库
给更多同学添加 域score
score:{english:87,chinese:76,math:91}

1. 按照性别统计每组人数
aggregate({$group:{_id:'$sex',num:{$sum:1}}})

2. 统计该班中有哪个同学姓名为重名同学
aggregate([{$group:{_id:'$name',num:{$sum:1}}},{$match:{num:{$gt:1}}}])

3. 统计所有男生的语文成绩,只打印姓名,性别,语文成绩即可
aggregate([{$match:{sex:'m'}},{$project:{_id:0,name:1,sex:1,'score.chinese':1}}])

4. 将所有女生按照英语成绩降序排序
aggregate([{$match:{sex:'w'}},{$sort:{'score.english':-1}}])

文件存储:

1.存储路径
将文件放在本地路径(网络路径)下,然后数据库中存储该文件的查找路径
  
优点 : 节省数据库空间
缺点 : 当数据或者 文件位置发生 变化时文件 即丢失

2. 将文件转换为二进制,存储文件本身

数据库支持二进制数据格式
将文件转换为二进制格式,然后存入数据库中

优点 : 数据库和文件绑定, 数据库文件即在
缺点 : 占用数据库空间大,存取效率低

mongodb存储文件本身
* 如果是 小文件建议转换 二进制直接插入
* 如果是 大文件建议使用 GridFS方案存储(大于16M)

GridFS方案解释

1. 在mongodb一个数据库中使用 两个集合配合存储文件
2. fs.files 用来存储文件的 相关信息,为每一个文件创建一个文档,
   存储文件 ,文件 大小,存入 时间。。。
3. fs.chunks 用来分块存储文件的实际内容( Binary data 类型数据)

存储方法:
mongofiles  -d dbname(数据库)   put  file(要存储的文件)
                                         

* 数据库不存在会自动创建数据库
  数据库中会 自动创建fs.files  fs.chunks两个集合

fs.files文档结构:
{
"_id" : ObjectId("5b7cdcd769d72e12b4f166d0"),
"chunkSize" : 261120,
"uploadDate" : ISODate("2018-08-22T03:47:35.381Z"),
"length" : 305033,
"md5" : "3698b5e762b5b396766aaf9feef7e10d", 
"filename" : "file.jpg"
}

fs.chunks文档结构
{
"_id" : ObjectId("5b7cdcd769d72e12b4f166d2"),
"files_id" : ObjectId("5b7cdcd769d72e12b4f166d0"), 
"n" : 1, 
"data" : BinData(0,"tQWR0AR......AG") 
}

* 同一个文件fs.files中的 _id值等于fs.chunks中的    files_id域的值

提取方法:

mongofiles  -d  dbname   get  file

GridFS方案:
优点 : 存储方便,提供较好的命令支持和编程接口
缺点 :  存取效率低下 还没有复制的快

mongo shell中获取游标
* mongo shell下支持JS代码,可以通过JS获取游标,进而获取数据操作结果。

var cursor = db.class1.find()
cursor.next()   获取下一条结果
cursor.hasNext()  查看是否有下一个对象


通过python操作 MongoDB:
pymongo 模块   第三方模块
安装:
sudo  pip3 install  pymongo

操作步骤:

    1. 连接数据库,生成数据库连接对象
        conn = pymongo.MongoClient('localhost',27017)

    2. 选择要操作的数据库,生成数据库对象 (__setitem__)
        db = conn.stu
        db = conn['stu']

    3. 获取集合对象
        myset = db.class0
        myset = db['class0']

    4. 通过集合对象调用mongodb数据库操作函数
        增删改查,聚合,索引。。。。。

    5. 关闭数据库连接
           conn.close()


插入文档:

insert()    插入数据 功能同 mongoshell
insert_many()  插入多条
insert_one() 插入一条
save()  插入数据,通过_id可以修改


查找操作:
find()
功能 : 对数据库进行查找
参数 : 同mongoshell  find()
返回值 : 返回游标对象
                cursor = myset.find({},{'_id':0})
cursor的属性函数
next()
limit()
skip()
count()
sort()

Python中sort和MongoDB的区别
                并且Python中的数据是字典和MongoDB的数据不同 
                所以键和操作符号都必须要加引号
pymongo  : sort([('age',-1),('name',1)])
mongoshell : sort({age:-1,name:1})

* 如果通过for或者next操作了游标对象,再调用limit,skip,sort会报错

find_one()
用法同mongoshell中 findOne()
返回一个字典


修改操作:
update(query,update,upsert = False,multi = False)
update_many()
update_one()

删除操作:
remove(query,multi = True)
功能: 删除文档
参数: query 筛选条件
       multi  默认True表示删除所有符合条件的
              False只删除一条

索引操作:
ensure_index()  创建索引
list_indexes()  查看索引
drop_index()  删除一个索引
drop_indexes() 删除所有索引

聚合操作:
aggregate([])
参数和mongoshell一样
返回值和find()函数一样也是得到一个游标对象


pymongo进行文件存取操作:

GridFS 文件提取:

import  gridfs
1. 连接数据库,获取相应的数据库对象
2. 通过 gridfs.GridFS(db) 获取集合对象(代表存储文件的两个集合)
3. 通过find()查找文件返回游标
4. 通过循环遍历游标获取指定文件对象,read()读取文件内容写入本地

以二进制的方式存取文件
import bson.binary


增删改查操作:


from pymongo import MongoClient 

#创建连接
conn = MongoClient('localhost',27017)

#创建数据库对象
db = conn.stu 

#创建集合对象
myset = db.class4 

print(dir(myset))

# 插入操作
myset.insert({'name':'张铁林','King':'乾隆'})
myset.insert([{'name':'张国立','King':'康熙'},\
    {'name':'陈道明','King':'康熙'}])
myset.insert_many([{'name':'唐国强','King':'雍正'},\
    {'name':'陈建斌','King':'雍正'}])
myset.insert_one({'name':'郑少秋','King':'乾隆'})
myset.save({'_id':1,'name':'聂远','King':'乾隆'}) 

# 查找操作

cursor = myset.find({},{'_id':0})

# i为每个文档对应的字典
for i in cursor:
    print(i['name'],'--->',i['King'])

myset = db.class1 
# 操作符使用引号变为字符串
cursor = myset.find({'age':{'$gt':30}},{'_id':0})

cursor.limit(2)#获取前两个文档
cursor.skip(2) #跳过前两个
cursor.sort([('age',-1),('name',1)]) #对游标内容排序

for i in cursor:
    print(i)
print(cursor.next()) #获取下一个文档


dic = {'$or':[{'age':{'$gt':35}},{'gender':'w'}]}
data = myset.find_one(dic,{'_id':0})
print(data)

# 修改操作
myset.update({'name':'张国立'},\
    {'$set':{'king_name':'玄烨'}})

myset.update({'name':'霍建华'},{'$set':{'King':'乾隆'}},\
    upsert = True)

myset.update({'King':'乾隆'},\
    {'$set':{'king_name':'弘历'}},multi = True)

myset.update_one({'King':'康熙'},\
    {'$set':{'king_name':'爱新觉罗玄烨'}})

myset.update_many({'King':'雍正'},\
    {'$set':{'king_name':'胤禛'}})

# 删除操作

myset.remove({'King':'康熙'})
myset.remove({'King':'乾隆'},multi = False)

#查找并删除
print(myset.find_one_and_delete({'King':'乾隆'}))


#关闭连接
conn.close()


索引操作:



from pymongo import MongoClient 

#创建连接
conn = MongoClient('localhost',27017)

#创建数据库对象
db = conn['stu'] 

myset = db['class1'] 

# 删除所有索引
myset.drop_indexes()

# 创建索引
index = myset.ensure_index('name')
# 创建复合索引
index = myset.ensure_index([('name',-1),('age',1)])
print(index)

# 删除一个索引
myset.drop_index('name_1')

# 创建特殊索引
index = myset.ensure_index('name',name = "myIndex",\
    unique = True,sparse = True)

# 查看集合中的索引
for i in myset.list_indexes():
    print(i)

myset = db.class4 

l = [
    {'$group':{'_id':'$King','num':{'$sum':1}}},
    {'$match':{'num':{'$gt':1}}}
]

cursor = myset.aggregate(l)
for i in cursor:
    print(i)

conn.close()



文件的存取:


from pymongo import MongoClient 
import bson.binary 

conn = MongoClient('localhost',27017)
db = conn.images 
myset = db.img 

#存储
f = open('file.jpg','rb')

#转换为mongodb的二进制数据存储形式
content = bson.binary.Binary(f.read())

#插入到数据库
myset.insert({'filename':'file.jpg','data':content})

#提取

data = myset.find_one({'filename':'file.jpg'})

#通过字典获取到数据库内容写入本地
with open(data['filename'],'wb') as f:
    f.write(data['data'])

conn.close()




手动存入文件MongoDB默认创建的文件数据导出:


from pymongo import MongoClient 
#pymongo绑定的模块
import gridfs

conn = MongoClient('localhost',27017)
db = conn.grid 

#获取gridfs对象
#fs综合了fs.files  fs.chunks两个集合的属性内容
fs = gridfs.GridFS(db)

#查文档生产游标
files = fs.find()

#获取每一个文件的对象
for file in files:
    print(file.filename)
    if file.filename == 'file.jpg':
        with open(file.filename,'wb') as f:
            #从数据库读取出来
            data = file.read()
            #写入本地
            f.write(data)

conn.close()


相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
1天前
|
NoSQL 安全 MongoDB
MongoDB为提供MongoDB数据库服务的云服务合作伙伴推出认证计划
Certified by MongoDB DBaaS计划还将为云计算合作伙伴提供构建深度技术集成所需的专业支持,同时还将携手MongoDB合作伙伴生态系统(MongoDB Partner Ecosystem)共同推出一系列联合的进入市场举措,使云服务合作伙伴能够助力其客户快速走向成功。
|
1天前
|
存储 NoSQL atlas
2024年向量数据库推荐榜单之MongoDB
目前市面上有哪些向量数据库解决方案,可协助您存储和检索高维向量?在推荐优选的几款向量数据库和库之前,我们需要厘清以下这两种技术的差异。
|
10天前
|
存储 NoSQL MongoDB
使用mongodb数据库实例
【5月更文挑战第9天】MongoDB中的集合类似关系数据库的表,但不强制模式,允许嵌入式文档以实现更灵活的数据布局。安装MongoDB在Ubuntu上涉及添加源列表和更新,CentOS则需创建配置文件。MongoDB支持备份和恢复,以及全文搜索。其灵活模式和动态模式减少了开发中的复杂性,但并非无模式,大部分数据仍具结构化特点。
86 2
|
12天前
|
存储 SQL NoSQL
什么是 MongoDB,为什么它是当今最受欢迎的数据库之一?
什么是 MongoDB,为什么它是当今最受欢迎的数据库之一?
|
14天前
|
NoSQL atlas MongoDB
Nosql数据库MongoDB的使用场景
【5月更文挑战第5天】 MongoDB是全球性的多云数据库,可在私有、公共和混合云中运行,提供高可用性、扩展性和合规性。 安全特性包括认证、授权、审计、网络隔离和加密。可提供跨云操作、可视化工具、搜索功能和数据湖支持,适用于现代应用开发,包括边缘数据处理。
47 1
|
14天前
|
JSON NoSQL MongoDB
理解Nosql数据库的mongodb
【5月更文挑战第5天】MongoDB是2009年发布的一款通用型NoSQL数据库,结合了关系模型和NoSQL的优点,适用于各种现代应用。其特点包括图形界面、数据服务、云基础设施集成(AWS, Azure, Google Cloud)。它具备全面的查询能力、ACID事务、可调整的一致性保证,并有多语言驱动及工具,可在任何地方运行。
79 4
|
Python
Python编程:二进制,八进制,十六进制与十进制之间的转换
Python编程:二进制,八进制,十六进制与十进制之间的转换
210 0
|
1天前
|
Python
深度解析Python中的多线程编程
深度解析Python中的多线程编程
21 1
|
5天前
|
机器学习/深度学习 数据处理 算法框架/工具
Python标准库与第三方库:强大的编程资源
Python标准库与第三方库:强大的编程资源
|
5天前
|
Python 容器
Python与GUI编程:创建图形用户界面
Python的Tkinter库是用于构建GUI应用的内置工具,无需额外安装。它提供了丰富的控件,如按钮、文本框等,让用户通过图形界面与程序交互。创建GUI窗口的基本步骤包括:导入Tkinter库,创建窗口对象,设置窗口属性,添加控件(如标签和按钮),并使用布局管理器(如`pack()`或`grid()`)来组织控件的位置。此外,可以通过绑定事件处理函数来响应用户操作,例如点击按钮。Tkinter还有更多高级功能,适合开发复杂GUI应用。