Python全栈 MongoDB 数据库(聚合、二进制、GridFS、pymongo模块),mongodbpymongo
断网了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()
本站文章为和通数据库网友分享或者投稿,欢迎任何形式的转载,但请务必注明出处.
同时文章内容如有侵犯了您的权益,请联系QQ:970679559,我们会在尽快处理。