python3.6连接MongoDB

  • 2018-09-09
  • 1,264
  • 2
# 多行输出结果
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'}

版权声明: 本网站所有资源采用BY-NC-SA 4.0协议进行授权,转载应当以相同方式注明文章来自:python3.6连接MongoDB - 一方的天地

评论

  • potoo回复

    评论测评

    • root回复

      评论审核测评

发表评论

陕ICP备18010914号
知识共享许可协议
本作品由一方天地采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资源请尽快联系站长,本站会在24h内删除有争议的资源。 -