目录
- 固定集合
- 文件储存、提取
- 游标
- pymongo模块
- 插入操作
- 查找操作
- 修改与删除操作
- 索引操作
- 聚合操作
- 文件操作
1. 固定集合
固定集合:
mongoDB中可以创建大小固定的集合, 成为固定集合
特点: 能够淘汰早期数据 (饱和状态)
插入和顺序查找速度更快(磁盘连续区域存储)
可以控制集合的空间大小
使用: 临时缓存 ; 日志处理
创建固定集合
db.createCollection('collection_name', {capped:true,size:10000,max:1000})
参数: capped: true 表示创建固定集合
size: 表示指定集合的大小 (bytes)
max: 指定集合存放文档数量上限
size 和 max 二者选最低
eg: db.createCollection("log",{capped:true,size:1000,max:3})
2. 文件储存、提取
文件存储方式:
1.存储文件路径 (链接形式)
eg:db.log.insert({filename:'test.pdf',size:40.1,path:'''/home/python/mongodb/test.pdf'})
优点: 节省数据库空间, 操作简单快捷
缺点: 当数据库或文件位置发生变化时, 需要修改数据库内容
2.存储文件本身 (二进制格式存储)
优点: 数据库在文件就在, 不会受到迁移的影响
缺点: 占用数据库空间大, 存储效率低
文件较大时 ( size>16MB )
GridFS 存储方案:
在mongoDB中以两个集合配合的方法来存储文件
其中一个集合为 fs.files : 存储文件相关信息(文件名,文件类型)
另一个为 fs.chunks : 分块存储文件的实际内容
存储文件:
$mongofiles -d dbname put file
dbname: 要将文件存入的数据库, 如果不存在会自动创建
file: 要保存的文件
eg: ~$ mongofiles -d grid put /home/python/mongodb/test.pdf
> db.fs.files.find().pretty()
{ "_id" : ObjectId("5d74b0d069d72e0d196bef26"),
"chunkSize" : 261120,
"uploadDate" : ISODate("2019-09-08T07:42:09.224Z"),
"length" : 52451491,
"md5" : "f6ed0109b2a4c3d9ba63399121459fbc",
"filename" : "/home/tarena/python/mongodb/test.pdf" }
>db.fs.chunks.find().pretty()
{ "_id" : ObjectId("5d74b0d069d72e0d196bef38"),
"files_id" : ObjectId("5d74b0d069d72e0d196bef26"),
"n" : 17,
"data" : BinData(0,"ih/Qv38nPqJs0Nw+WZU......") }
注意: fs.files._id == fs.chunks.files_id
提取文件 :
$ mongofiles -d dbname get file
eg: ~$ mongofiles -d grid get /home/python/mongodb/test.pdf
GridFS存储方式的优缺点:
优点: 操作方便, 提供较好的存储命令, 使用数据库存储文件方便移植
缺点: 读写效率低
3. 游标
游标 cursor
通过获取操作数据库的返回结果, 得到返回结果对象
通过游标可以进一步获取操作结果数据
mongo shell 支持 javaScript 编程
eg: 将返回结果赋给一个js变量, 作为查找结果游标
var cursor = db.class.find()
查看是否有下一个结果
cursor.hasNext()
获取下一个结果
cursor.next()
4. pymongo模块
pymongo 模块:
安装: sudo pip3 install pymongo
操作步骤:
1.创建mongodb的数据库连接对象
conn = pymongo.MongoClient('localhost',27017)
2.生成数据库对象(__setitem__ ; __getitem__)
db = conn.stu
db = conn['stu']
3.生成集合对象
myset = db.class
myset = db['class']
4.进行集合操作(增 删 改 查 索引 聚合)
5.关闭数据库连接
conn.close()
注: python--->mongo
True ---> true ; False ---> false ; None ---> null
5. 插入操作
插入新的文档:
insert()
insert_many()
insert_one()
save()
eg:
#myset.insert({'name':'张铁林','King':'乾隆'})
#myset.insert_many([{'name':'张国立','King':'康熙'},{'name':'陈道明','King':'康熙'}])
#myset.insert([{'name':'唐国强','King':'雍正'},{'name':'陈建斌','King':'雍正'}])
#myset.insert_one({'name':'郑少秋','King':'乾隆'})
#myset.save({'_id':1,'name':'聂远','King':'乾隆'})
myset.save({'_id':1,'name':'吴奇隆','King':'四爷'}) # _id 相同时覆盖
6. 查找操作
查找操作
find()
功能: 查找数据库内容
参数: 同 mongo shell find()
返回值: 返回一个结果游标对象
eg:
cursor = myset.find({},{'_id':0})
for i in cursor:
print(i['name'],'---',i['King'])
find_one()
功能: 查询第一条符合条件的文档
参数: 同 find()
返回值: 返回一个字典
eg:
cursor = myset.find_one({},{'_id':0})
print(cursor)
操作符的使用 :
pymongo中所有操作符的用法同 mongo shell
只是操作时加入 ' ' , 以字符串的方式写入 python 代码
eg:
cursor = myset1.find({'age':{'$gt':18}},{'_id':0})
for i in cursor:
print(i)
cursor 对象的属性:
next()
limit()
skip()
count()
sort() #与mongo用法有所区别 eg: cursor.sort([('age',1),('name',-1)])
mongo shell : sort({age:1,name:-1})
注: 使用 for 或者 next 使游标位置不再指向开头位置的时候
调用 limit skip sort 就会报错
eg:
#cursor = myset1.find({'age':{'$gt':18}},{'_id':0})
#print(cursor.next())
#print(cursor.next())
#for i in cursor.skip(1).limit(3):
# print(i)
#for i in cursor.sort([('age',1),('name',-1)]):
# print(i)
query = {'$or':[{'gender':'w'},{'age':{'lt':19}}]}
cursor = myset1.find(query,{'_id':0})
for i in cursor:
print(i)
7. 修改与删除操作
修改操作:
update(query,update,upsert = False, multi = False)
update_mant()
update_one()
eg:
#cursor = myset1.update({'name':'Jame'},{'$unset':{'tel':''}})
#cursor = myset1.update({'name':'Jame'},{'$set':{'age':21}},False,True)
#如果匹配文档不存在则插入
#myset.update({'name':'梁家辉'},{'$set':{'King':'咸丰'}},upsert = True)
#myset.update_one({'King':'乾隆'},{'$set':{'KingName':'弘历'}})
myset.update_one({'King':'康熙'},{'$set':{'KingName':'玄烨'}})
删除操作:
remove(query,multi = True)
#multi default: True 删除所有过滤到的文档
eg:
#myset.remove({'King':'四爷'})
#myset.remove({'King':'咸丰'},multi = False)
myset1.remove({'gender':{'$exists':False}})
复合函数:
eg:find_one_and_delete 查找第一条符合条件的文档并删除
print(myset.find_one_and_delete({'King':'咸丰'}))
8. 索引操作
索引操作:
ensure_index()
list_indexes()
drop_index()
drop_indexes()
eg:
#index = myset.ensure_index('name')
#index = myset.ensure_index([('age',-1)])
#for i in myset.list_indexes():
# print(i)
#删除所有索引
#myset.drop_indexes()
#index = myset.ensure_index('name')
#print(index)
#删除单个索引
#myset.drop_index('name_1')
#创建复合索引
#myset.ensure_index([('name',1),('age',-1)])
#创建唯一索引
#myset.ensure_index('name',name="MyIndex",unique = True)
#创建稀疏索引
#myset.ensure_index('age',name="AgeIndex",sparse = True)
9. 聚合操作
聚合操作:
aggregate({})
参数: 和 mongo shell 一样
返回值: 和 find() 函数相同的游标对象
eg:显示至少有两个人扮演的皇帝
p = [ {'$group':{'_id':'$King','count':{'$sum':1}}},
{'$match':{'count':{'$gt':1}}}]
cursor = myset1.aggregate(p)
for i in cursor:
print(i)
conn.close()
eg:
1.为所有人添加分数域,值为一个字典
from random import randint
cursor = myset.find()
for i in cursor:
myset.update({'_id':i['_id']},
{'$set':{'score':{'Chinese':randint(60,100),
'Math':randint(60,100),'English':randint(60,100)
}}} )
2.按照性别分组,统计每组人数
p1 = [{ '$group': {'_id': '$sex', count:{'$sum': 1}}}]
3.统计每名男生的语文成绩
p2 = [
{'$match':{'sex':'m'}},
{'$project':{'_id':0,'name':1,'score.Chinese':1}}
]
4.将女生按照英语成绩降序排列
p3 = [
{'$match':{'sex':'w'}},
{'$sort':{'score.English':-1}}
]
cursor = myset.aggregate(pi)
for i in cursor:
print(i)
conn.close()
10.文件操作
pymongo 实现 GridFS存储
import gridfs
GridFS()
功能: 生成grid数据库对象
存储小文件时:
import bson
bson.binary.Binary()
功能 : 将bytes格式子串转换为mongodb的二进制存储格式
#将文件以GridFS方案存入数据库
from pymongo import MongoClient
import gridfs
conn = MongoClient('localhost',27017)
db = conn.grid
#获取gridfs对象
fs = gridfs.GridFS(db)
f = open('test.JPG','rb')
#将内容写入到数据库
fs.put(f.read(),filename = 'test.JPG')
conn.close()
f.close()
#获取数据库中文件
from pymongo import MongoClient
import gridfs
conn = MongoClient('localhost',27017)
db = conn.grid
#获取gridfs对象
fs = gridfs.GridFS(db)
#得到文件集合对象
files = fs.find()
#分别获取每个文件
for file in files:
#打印每个文件名称
print(file.filename)
if file.filename == 'test.JPG':
with open(file.filename,'wb') as f :
#从数据库中读取文件
data = file.read()
#写入到本地
f.write(data)
conn.close()
#小文件存储方案
#直接转换为二进制格式插入到数据库中
from pymongo import MongoClient
import bson
import time
conn = MongoClient('localhost',27017)
db = conn.image
myset = db.image1
#存储图片
f = open('test.JPG','rb')
#将图片内容转换为可存储的二进制格式
content = bson.binary.Binary(f.read())
#插入到文档
myset.insert({'filename':'test.JPG',
'date':time.ctime(),
'data':content})
f.close()
#从数据库中获取二进制保存的图片
from pymongo import MongoClient
conn = MongoClient('localhost',27017)
db = conn.image
myset = db.image1
img = myset.find_one({'filename':'test.JPG'})
#将内容写入到本地(自动转换为python可识别的格式)
with open('test.JPG','wb') as f :
f.write(img['data'])
conn.close()