# 多行输出结果
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
1. 连接mongodb
import pymongo as pmg
# 无权限认证
# client = pmg.MongoClient(host='localhost', port=27017)
# 也可以使用链接形式来连接
# client = pmg.MongoClient('mongodb://localhost:27017')
# 权限认证登陆
client = pmg.MongoClient(host='localhost', port=27017)
db_auth = client.admin
db_auth.authenticate('testuser', 'testpass')
True
2. 获取数据库列表, 并连接
client.list_database_names()
# 如果不存在数据库下面命令会创建数据库
db = client.test_database
# 也可以这样指定
# db = client['test_database']
# db = client.get_database('test_database')
['test_database']
3. 获取集合列表,并连接
mongodb的每个数据库包括许多集合(collection), 类似于关系数据库中的表
db.list_collection_names()
# col_info = db.list_collections()
# print(list(col_info))
collection = db.test_collection # 等同于 collection = db['test_collection']
['test_collection']
4. 插入数据
4.1 插入单条数据 — insert_one()方法
新建一组学生数据,以字典形式表示
student = {
'id': '20180820',
'name': 'Morty',
'age': 20,
'gender': 'male'
}
# 使用insert_one方法插入数据
result = collection.insert_one(student)
在Mongodb中每条数据都有一个_id属性来唯一标识。如果没有显示指定该值,MongoDB会自动产生_id,insert()方法会返回_id
print(result)
print(result.inserted_id)
<pymongo.results.InsertOneResult object at 0x0000025D2AA75788>
5b7a402c3f59e220a0aeb66a
4.2 插入多条数据 — insert_many()方法
student1 = {
'id': '20180820',
'name': 'Heisenberg',
'age': 20,
'gender': 'male'
}
student2 = {
'id': '20200820',
'name': 'Dirac',
'age': 30,
'gender': 'male'
}
# 使用insert_many方法插入多条数据,参数是列表形式
result = collection.insert_many([student1, student2])
5. 查询数据 — find, find_one
find_one() 查询得到是单个结果,find() 则返回一个生成器对象。
5.1 查询单条数据 — find_one()方法
# 查看集合的所有key。类似关系型数据库的字段
collection.find_one().keys()
result = collection.find_one({'name': 'Dirac'})
print(type(result))
print(result)
dict_keys(['_id', 'id', 'name', 'age', 'gender'])
<class 'dict'>
{'_id': ObjectId('5b7a42343f59e220a0aeb66c'), 'id': '20200820', 'name': 'Dirac', 'age': 32, 'gender': 'male'}
也可以根据_id属性来查找
from bson.objectid import ObjectId
result = collection.find_one({'_id': ObjectId('5b7a42343f59e220a0aeb66c')})
print(type(result))
print(result)
<class 'dict'>
{'_id': ObjectId('5b7a42343f59e220a0aeb66c'), 'id': '20200820', 'name': 'Dirac', 'age': 32, 'gender': 'male'}
5.2 查询多条数据 — find()方法
results = collection.find({'age': 20})
print(results)
for result in results:
print(result)
<pymongo.cursor.Cursor object at 0x00000118CBCD5908>
查询记录总数
collection.find().count()
D:\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: count is deprecated. Use Collection.count_documents instead.
"""Entry point for launching an IPython kernel.
3
5.3 匹配规则
5.3.1 比较符号
符号 | 含义 | 示例 |
---|---|---|
lt | 小于 | {‘age’: {‘lt’: 20}} |
gt | 大于 | {‘age’: {‘gt’: 20}} |
lte | 小于等于 | {‘age’: {‘lte’: 20}} |
gte | 大于等于 | {‘age’: {‘gte’: 20}} |
ne | 不等于 | {‘age’: {‘ne’: 20}} |
in | 在范围内 | {‘age’: {‘in’: [20, 23]}} |
nin | 不在范围内 | {‘age’: {‘nin’: [20, 23]}} |
如果要查询年龄大于 20 的数据,则写法如下
results = collection.find({'age': {'$gt': 19}})
list(results)
[{'_id': ObjectId('5b7a42343f59e220a0aeb66b'),
'age': 27,
'gender': 'male',
'id': '20180820',
'name': 'Heisenberg'},
{'_id': ObjectId('5b7a42343f59e220a0aeb66c'),
'age': 32,
'gender': 'male',
'id': '20200820',
'name': 'Dirac'}]
5.3.2 功能符号
符号 | 含义 | 示例 | 示例含义 |
---|---|---|---|
regex | 匹配正则 | {‘name’: {‘regex’: ‘^M.*’}} | name 以 M开头 |
exists | 属性是否存在 | {‘name’: {‘exists’: True}} | name 属性存在 |
type | 类型判断 | {‘age’: {‘type’: ‘int’}} | age 的类型为 int |
mod | 数字模操作 | {‘age’: {‘mod’: [5, 0]}} | 年龄模 5 余 0 |
text | 文本查询 | {‘text’: {‘search’: ‘Mike’}} | text 类型的属性中包含 Mike 字符串 |
where | 高级条件查询 | {‘where’: ‘obj.fans_count == obj.follows_count’} | 自身粉丝数等于关注数 |
results = collection.find({'name': {'$regex': '^M.*'}})
list(results)
[{'_id': ObjectId('5b7a402c3f59e220a0aeb66a'),
'age': 20,
'gender': 'male',
'id': '20180820',
'name': 'Morty'}]
6. 计数 — count()方法
count = collection.find().count()
print(count)
3
D:\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: count is deprecated. Use Collection.count_documents instead.
"""Entry point for launching an IPython kernel.
count = collection.find({'age': 20}).count()
print(count)
2
D:\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: count is deprecated. Use Collection.count_documents instead.
"""Entry point for launching an IPython kernel.
7. 排序 — sort()方法.
升序排序pymongo.ASCENDING, 降序pymongo.DESCENDING
results = collection.find().sort('name', pmg.ASCENDING)
print([result['name'] for result in results])
['Dirac', 'Heisenberg', 'Morty']
8. 偏移 — skip() 方法
在某些情况下我们可能想只取某几个元素,在这里可以利用skip() 方法偏移几个位置,比如偏移 2,就忽略前 2 个元素,得到第三个及以后的元素。
results = collection.find().sort('name', pmg.ASCENDING).skip(1)
print([result['name'] for result in results])
['Heisenberg', 'Morty']
另外还可以用 limit() 方法指定要取的结果个数,示例如下
results = collection.find().sort('name', pmg.ASCENDING).skip(1).limit(1)
print([result['name'] for result in results])
['Heisenberg']
值得注意的是,在数据库数量非常庞大的时候,如千万、亿级别,最好不要使用大的偏移量来查询数据,很可能会导致内存溢出,可以使用类似如下操作来进行查询:
from bson.objectid import ObjectId
collection.find({'_id': {'$gt': ObjectId('593278c815c2602678bb2b8d')}})
这时记录好上次查询的 _id。
9. 更新 — update_one(), update_many()
condition = {'name': 'Morty'}
student = collection.find_one(condition)
print(student['age'])
student['age'] = 14
result = collection.update(condition, student)
## 另外我们也可以使用 $set 操作符对数据进行更新,代码改写如下:
# result = collection.update(condition, {'$set': student})
print(result)
student = collection.find_one(condition)
print(student['age'])
16
{'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}
14
D:\Anaconda3\lib\site-packages\ipykernel_launcher.py:5: DeprecationWarning: update is deprecated. Use replace_one, update_one or update_many instead.
"""
9.1 更新单个 — update_one()
第二个参数不能再直接传入修改后的字典,而是需要使用 {'$set': student}
这样的形式,其返回结果是 UpdateResult 类型,然后调用 matched_count 和 modified_count 属性分别可以获得匹配的数据条数和影响的数据条数。
condition = {'name': 'Morty'}
student = collection.find_one(condition)
print(student['age'])
student['age'] = 16
result = collection.update_one(condition, {'$set': student})
print(result)
print(result.matched_count, result.modified_count)
student = collection.find_one(condition)
print(student['age'])
14
<pymongo.results.UpdateResult object at 0x0000018AB1323648>
1 1
16
使用比较符号来匹配数据
下面例子:
在这里我们指定查询条件为年龄大于 20,然后更新条件为 {'$inc': {'age': 1}}
,也就是年龄加 1,执行之后会将第一条符合条件的数据年龄加 1。
condition = {'age': {'$gt': 18}}
result = collection.update_one(condition, {'$inc': {'age': 1}})
print(result)
print(result.matched_count, result.modified_count)
<pymongo.results.UpdateResult object at 0x0000018AB12B1348>
1 1
9.1 更新多个 — update_many()
condition = {'age': {'$gt': 16}}
result = collection.update_many(condition, {'$inc': {'age': 1}})
print(result)
print(result.matched_count, result.modified_count)
<pymongo.results.UpdateResult object at 0x0000018AB122AC48>
3 3
10. 删除 — delete_one(), delete_many()
10.1 删除单个 — delete_one()
可以调用 deleted_count 属性获取删除的数据条数
condition = {'name': 'Morty'}
result = collection.delete_one(condition)
print(result)
print(result.deleted_count)
student = {
'id': '20180820',
'name': 'Morty',
'age': 14,
'gender': 'male'
}
# 使用insert_one方法插入数据
result = collection.insert_one(student)
<pymongo.results.DeleteResult object at 0x0000018AB1339688>
1
10.2 删除多个 — delete_many()
可以调用 deleted_count 属性获取删除的数据条数
condition = {'age': {'$lt': 18}}
result = collection.delete_many(condition)
print(result)
print(result.deleted_count)
student = {
'id': '20180820',
'name': 'Morty',
'age': 14,
'gender': 'male'
}
# 使用insert_one方法插入数据
result = collection.insert_one(student)
<pymongo.results.DeleteResult object at 0x0000018AB1227448>
1
11. more
另外 PyMongo 还提供了一些组合方法,如find_one_and_delete()、find_one_and_replace()、find_one_and_update(),就是查找后删除、替换、更新操作,用法与上述方法基本一致。
另外还可以对索引进行操作,如 create_index()、create_indexes()、drop_index() 等。
详细用法可以参见官方文档:http://api.mongodb.com/python/current/api/pymongo/collection.html
另外还有对数据库、集合本身以及其他的一些操作,在这不再一一讲解,可以参见官方文档:http://api.mongodb.com/python/current/api/pymongo/
综合实验 — 插入量子力学部分科学家信息
import json
import pymongo as pmg
# 登录MongoDB
client = pmg.MongoClient(host='localhost', port=27017)
db_auth = client.admin
db_auth.authenticate('testuser', 'testpass')
# 连接数据表
db = client.test_database
db.list_collection_names()
# 连接集合
collection = db.Quantum_mechanics_scientist
# # 删除集合
# collection.drop()
# db.list_collection_names()
# 删除集合里原数据
result = collection.delete_many({'NAME': {'$regex': '.*'}})
print('deleted_count: ', result.deleted_count)
# 获取数据
with open('test_json.json', 'r') as file:
txt = file.read()
data = json.loads(txt)
# 上传至MongoDB
result = collection.insert_many(data)
print('\nUpload Successful? ', result.acknowledged, end='\n\n')
# 读取MongoDB的数据
results = collection.find()
for result in results:
print(result)
True
['Quantum_mechanics_scientist', 'test_collection']
deleted_count: 9
Upload Successful? True
{'_id': ObjectId('5b8761933f59e20d38dfb056'), 'NAME': 'Planck', 'FULL NAME': 'Max Karl Ernst Ludwig Planck', 'BIRTH': '1858', 'KNOWN FOR': 'The Planck–Einstein relation', 'NATIONALITY': 'Germany'}
{'_id': ObjectId('5b8761933f59e20d38dfb057'), 'NAME': 'Dirac', 'FULL NAME': 'Paul Adrien Maurice Dirac', 'BIRTH': '1902', 'KNOWN FOR': 'Dirac equation', 'NATIONALITY': 'UK'}
{'_id': ObjectId('5b8761933f59e20d38dfb058'), 'NAME': 'Bohr', 'FULL NAME': 'Niels Henrik David Bohr', 'BIRTH': '1885', 'KNOWN FOR': 'Bohr model', 'NATIONALITY': 'Denmark'}
{'_id': ObjectId('5b8761933f59e20d38dfb059'), 'NAME': 'Faraday', 'FULL NAME': 'Michael Faraday', 'BIRTH': '1791', 'KNOWN FOR': 'Electromagnetic induction', 'NATIONALITY': 'UK'}
{'_id': ObjectId('5b8761933f59e20d38dfb05a'), 'NAME': 'Lorentz', 'FULL NAME': 'Hendrik Antoon Lorentz', 'BIRTH': '1853', 'KNOWN FOR': 'Lorentz force', 'NATIONALITY': 'Netherlands'}
{'_id': ObjectId('5b8761933f59e20d38dfb05b'), 'NAME': 'Feynman', 'FULL NAME': 'Richard Phillips Feynman', 'BIRTH': '1988', 'KNOWN FOR': 'Feynman diagrams, Feynman rules', 'NATIONALITY': 'US'}
{'_id': ObjectId('5b8761933f59e20d38dfb05c'), 'NAME': 'Einstein', 'FULL NAME': 'Albert Einstein', 'BIRTH': '1879', 'KNOWN FOR': 'Photoelectric Effect, Mass–energy equivalence, Special relativity, General relativity', 'NATIONALITY': 'US'}
{'_id': ObjectId('5b8761933f59e20d38dfb05d'), 'NAME': 'Heisenberg', 'FULL NAME': 'Werner Heisenberg', 'BIRTH': '1901', 'KNOWN FOR': 'Uncertainty principle', 'NATIONALITY': 'Germany'}
{'_id': ObjectId('5b8761933f59e20d38dfb05e'), 'NAME': 'Schrödinger', 'FULL NAME': 'Erwin Rudolf Josef Alexander Schrödinger', 'BIRTH': '1887', 'KNOWN FOR': "Schrödinger equation, Schrödinger's cat", 'NATIONALITY': 'Austria'}
评论测评
评论审核测评