MongoDB存储
MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统。其内容存储形式类似JSON对象,它的字段可以包含其他文档,数组,文档数组。
1.准备
安装MongoDB,并启动服务。
安装PyMongo库。
2.基本操作
连接MongoDB
import pymongo
client=pymongo.MongoClient(host='localhost',port=27017)
#client=pymongo.MongoClient('mongodb://localhost:27017')#或者直接传入字符串
print(client)
指定数据库
#指定MongoDB的test数据库
db=client.test
#db=client['test']
指定集合
Mongo的数据库包含了很多集合(collection),类似于关系型数据库中的表。
collection=db.students
#collection=db['students']
3.插入数据
student={
'id':'10023',
'name':'Tom',
'age':23
}
res=collection.insert(student)
print(res)
'''
运行输出:
5def8e96c4203d31b90ea4ea
'''
MongoDB中,每条数据都有一个_id属性来唯一标识。没有显示指明该属性,由MongoDB默认生成一个ObjectId类型的 _id属性。调用insert()方法后返回该属性。
若以列表的形式插入
stu=[{
'id': '10024',
'name': 'Mary',
'age': 20
},{
'id': '10025',
'name': 'Mike',
'age': 25
}]
res=collection.insert(stu)
print(res)
'''
[ObjectId('5def901e729d50c3021e1226'), ObjectId('5def901e729d50c3021e1227')]
'''
python3.x版本中,也可以使用insert_one()和insert_many()方法来实现插入单条记录和多条记录,官方推荐。
res1=collection.insert_one(student)
res2=collection.insert_many(stu)
print(res1)
print(res1.inserted_id)
print(res2)
print(res2.inserted_ids)
'''
<pymongo.results.InsertOneResult object at 0x000001B44BA42F88>
5def91cc6ecbe6fd31a1968e
<pymongo.results.InsertManyResult object at 0x000001B44BA42C08>
[ObjectId('5def91cc6ecbe6fd31a1968f'), ObjectId('5def91cc6ecbe6fd31a19690')]
'''
4.查询
find_one()和find()方法进行查询。find_one()是单个结果,find()返回的是生成器对象。
res=collection.find_one({'name':'Mike'})
print(res)
print(type(res))
'''
{'_id': ObjectId('5def901e729d50c3021e1227'), 'id': '10025', 'name': 'Mike', 'age': 25}
<class 'dict'>
'''
find()方法。查找年龄为20的数据
results = collection.find({'age': 20})
print(results)
for res in results:
print(res)
查找年龄>20的数据。
results=collection.find({'age': {'$gt': 20}})
for res in results:
print(res)
比较符号
$lt 小于,$gt 大于,$lte 小于等于,$gte 大于等于,$ne 不等于,$in 在范围内 ,$nin 不在范围内。
results=collection.find({‘name’: {‘$regex’: ‘^M.*’}}),$regex来指定正则匹配,查询以M开头的正则表达式。
功能符号
$regex ————正则表达式 ——————— {‘name’: {‘$regex’: ‘^M.*’}}
$exists ————属性是否存在 ———— ——{‘$name’: { ‘$exists’: True}} name属性是否存在。
$type ———— 类型判断 ————————{‘age’: {‘$type’: ‘int’}} age的类型为int
$mod ———— 数字模操作———————{‘age’: {‘$mod’: [5,0]}} age取模余数为0
$text ———— 文本查询————————{‘$text’: {‘$serach’: ‘Mike’}} text类型的属性中包含Mike字符串
$where ————高级查询————————{‘$where’: ‘age==20’} age为20
5.计数与排序
计数
# cnt=collection.find().count() cnt=collection.find({'age': {'$lte': 25}}).count() print(cnt)
排序
results=collection.find().sort('name',pymongo.ASCENDING)#按name升序,降序为pymongo.DESCENDING print([result['name'] for result in results]) ''' ['Mary', 'Mary', 'Mary', 'Mary', 'Mary', 'Mike', 'Mike', 'Mike', 'Mike', 'Mike', 'QQ', 'Tom', 'Tom', 'Tom', 'Tom', 'Tom', 'Wed'] '''
6.偏移
利用skip()方法偏移取的元素,比如偏移两个2,就忽略前两个元素,得到第三个以后的元素。
results=collection.find().sort('name',pymongo.ASCENDING).skip(2)
print([res['name'] for res in results])
'''
['Mary', 'Mary', 'Mary', 'Mike', 'Mike', 'Mike', 'Mike', 'Mike', 'QQ', 'Tom', 'Tom', 'Tom', 'Tom', 'Tom', 'Wed']
'''
或者使用limit()方法指定要取的个数。
results=collection.find().sort('name',pymongo.ASCENDING).limit(2)
print([res['name'] for res in results])
'''
['Mary', 'Mary']
'''
当数据量非常大的时候,使用偏移量容易内存溢出。可以保留上次的 _id,在通过 _id的进行取数据。
from bson.objectid import ObjectId
id1=collection.find_one()['_id']
print(id1)
results=collection.find({'_id':{'$gt': ObjectId(id1)}})
print([res['name'] for res in results])
'''
5def8e96c4203d31b90ea4ea
['Mary', 'Mike', 'Tom', 'Mary', 'Mike', 'Tom', 'Mary', 'Mike', 'Tom', 'Mary', 'Mike', 'Tom', 'Mary', 'Mike', 'QQ', 'Wed']
'''
7.更新
condition={'name': 'Mary'}
student=collection.find_one(condition)
student['age']=25
#result=collection.update(condition,student)
#不使用set会将匹配的数据库的数据全部用student替换,如果原先存在其他字段会被删除
result=collection.update(condition,{'$set': student})
print(result)
'''
{'n': 1, 'nModified': 0, 'ok': 1.0, 'updatedExisting': True}
'''
或者,官方推荐使用update_one()和update_many()方法。它们的第二个参数需要使用$操作符作为字典的键名。
condition={'name': 'Mary'}
student=collection.find_one(condition)
student['age']=26
result=collection.update_one(condition,{'$set': student})#update_once返回的结果是UpdateResult类型
#set操作符可以只更新student字典内存在的字段,如果原先还有其他字段,则不变。
print(result.matched_count,result.modified_count)#分别获得匹配的数据条数和影响的数据条数
'''
1 1
'''
改变更新条件
condition={'age': {'$gt': 20}}
result=collection.update_one(condition,{'$inc': {'age': 1}})
#查询年龄>20记录,更新条件为{'$inc': {'age': 1}},将这条记录的年龄加 1
print(result.matched_count,result.modified_count)
print(type(result))
'''
1 1
<class 'pymongo.results.UpdateResult'>
'''
update_many()方法
condition={'age':{'$gt': 20}}
result=collection.update_many(condition,{'$inc':{'age': 1}})
print(result.matched_count,result.modified_count)
8.删除
直接调用remove()方法即可进行删除。
condition={'name': 'Mary'}
result=collection.remove(condition)
print(result)
#此时符合条件的所有数据均会被删除
'''
{'n': 5, 'ok': 1.0}
'''
新的推荐方法 delete_one()和delete_many()
res=collection.find()
print([r['name'] for r in res])
condition={'name': 'Tom'}
result=collection.delete_one(condition)
print(result)
print(result.deleted_count)
result=collection.delete_many({'age': {'$lt': 23}})
print(result.deleted_count)
res=collection.find()
print([r['name'] for r in res])
'''
['Mike', 'Mike', 'Tom', 'Mike', 'Tom', 'Mike', 'Tom', 'Mike']
<pymongo.results.DeleteResult object at 0x000002B1B1FA1F08>
1
0
['Mike', 'Mike', 'Mike', 'Tom', 'Mike', 'Tom', 'Mike']
'''
9.其他方法
PyMongoDB提供了一些组合方法,如find_one_and_detele(),find_one_and_replace(),find_one_and_update(),
它们是查找后删除,替换和更新的操作。
对索引进行操作,create_index(),create_indexs()和drop_index()等。