by 極光
MongoDB 是一款面向文檔型的 NoSQL
數據庫,是一個基於分布式文件存儲的開源的非關系型數據庫系統,其內容是以 K/V
形式存儲,結構不固定,它的字段值可以包含其他文檔、數組和文檔數組等。其采用的 BSON
(二進制 JSON )的數據結構,可以提高存儲和掃描效率,但空間開銷會有些大。今天就為大家簡單介紹下在 Python 中使用 MongoDB 。
安裝 PyMongo 庫
在 Python 中操作 MongoDB ,需要使用 PyMongo
庫,執行如下命令安裝:
pip3 install pymongo
連接 MongoDB 數據庫
連接時需要使用 PyMongo 庫里面的 MongoClient 模塊,有兩種方式可以創建連接,默認只需要傳入IP和端口號即可。如果數據庫存在賬號密碼,則需要指定連接的數據庫,並進行鑒權才能連接成功。
#導入 MongoClient 模塊
from pymongo import MongoClient, ASCENDING, DESCENDING
# 兩種方式
#1. 傳入數據庫IP和端口號
mc = MongoClient('127.0.0.1', 27017)
#2. 直接傳入連接字串
mc = MongoClient('mongodb://127.0.0.1:27017')
# 有密碼的連接
# 首先指定連接testdb數據庫
db = mc.testdb
# 通過authenticate方法認證賬號密碼
db.authenticate('username','password')
# 檢查是否連接成功,輸出以下結果表示連接成功
print(mc.server_info())
# {'version': '4.2.1', 'gitVersion': 'edf6d45851c0b9ee15548f0f847df141764a317e', 'modules': [], 'allocator': 'tcmalloc', 'javascriptEngine': 'mozjs', 'sysInfo': 'deprecated', 'versionArray': [4, 2, 1, 0], 'openssl': {'running': 'OpenSSL 1.1.1 11 Sep 2018', 'compiled': 'OpenSSL 1.1.1 11 Sep 2018'}, ……省略 , 'ok': 1.0}
MongoDB 數據庫操作
成功連接數據庫,接下來我們開始介紹通過 MongoClient 模塊如何對 mongoDB 數據庫進行 CURD
的操作。
獲取數據庫和集合
首先要指定需要操作的數據庫和集合,這里的數據庫可以對應為 Mysql
的 DataBase
,集合對應為 Mysql
的 Table
。需要注意的是在 mongoDB 中,不需要提前創建數據庫和集合,在你操作它們時如果沒有則會自動創建,但都是延時創建的,在添加 Document
時才會真正創建。
# 指定操作數據庫的兩種方式
#1. 獲取 testdb 數據庫,沒有則自動創建
db = mc.testdb
#2. 效果與上面 db = mc.testdb 相同
db = mc['testdb']
# 打印出testdb數據庫下所有集合(表)
print(db.collection_names())
# 指定操作集合的兩種方式
#1. 獲取 test 集合,沒有則自動創建
collection = db.test
#2. 效果與 collection = db.test 相同
collection = db['test']
# 打印集合中一行數據
print(collection.find_one())
數據的插入操作
在 MongoDB 中,每條數據其實都有一個 _id
屬性作為唯一標識。如果沒有顯式指明該屬性,MongoDB 會自動產生一個 ObjectId
類型的 _id
屬性,insert()
方法會在執行后返回 _id
值。不過在 PyMongo 3.x 版本中,官方已經不推薦使用 insert()
方法,而是推薦使用insert_one()
和 insert_many()
方法來分別插入單條記錄和多條記錄。
# 要插入到集合中的對象
book = {
'name' : 'Python基礎',
'author' : '張三',
'page' : 80
}
# 向集合中插入一條記錄
collection.insert_one(book)
# 返回結果:{'_id': ObjectId('5de4c7b90ae08431839ac2a7'), 'name': 'Python基礎', 'author': '張三', 'page': 80}
# 對於insert_many()方法,我們可以將數據以列表形式傳遞參數
book1 = {
'name' : 'Java基礎',
'author' : '李白',
'page' : 100
}
book2 = {
'name' : 'Java虛擬機',
'author' : '王五',
'page' : 100
}
# 創建 book_list 列表
book_list = [book1, book2]
# 向集合中插入多條記錄
collection.insert_many(book_list)
# 返回結果: <pymongo.results.InsertManyResult object at 0x7f80a39fa408>
數據的查詢操作
查詢需要使用 find_one()
或 find()
方法,其中 find_one()
查詢得到的是單個結果,即一條記錄,find()
則返回一個生成器對象。下面我們就來查詢上面剛插入的數據,如果查詢不到數據則返回 None
,代碼如下:
# 通過條件查詢一條記錄,如果不存在則返回None
res = collection.find_one({'author': '張三'})
print (res)
# 打印結果:{'_id': ObjectId('5de4c7b90ae08431839ac2a7'), 'name': 'Python基礎', 'author': '張三', 'page': 80}
# 通過條件查詢多條記錄,如果不存在則返回None
res = collection.find({'page': 100})
print (res)
#打印結果:<pymongo.cursor.Cursor object at 0x7f80a39daa58>
# 使用 find() 查詢會返回一個對象
# 遍歷對象,並打印查詢結果
for r in res:
print(r)
#打印結果:
# {'_id': ObjectId('5de4c8ae0ae08431839ac2a8'), 'name': 'Java基礎', 'author': '李白', 'page': 100}
# {'_id': ObjectId('5de4c8ae0ae08431839ac2a9'), 'name': 'Java虛擬機', 'author': '王五', 'page': 100}
# 查詢page大於50的記錄
res = collection.find({'page': {'$gt': 50}})
# 通過遍歷返回對象,結果如下:
# {'_id': ObjectId('5de4c7b90ae08431839ac2a7'), 'name': 'Python基礎', 'author': '張三', 'page': 80}
# {'_id': ObjectId('5de4c8ae0ae08431839ac2a8'), 'name': 'Java基礎', 'author': '李白', 'page': 100}
# {'_id': ObjectId('5de4c8ae0ae08431839ac2a9'), 'name': 'Java虛擬機', 'author': '王五', 'page': 100}
上面查詢條件中我們用到了 $gt
的比較運算符,關於查詢條件中的比較運算符和功能運算符對照表如下:
符號 | 含義 | 舉例 |
---|---|---|
$gt | 大於 | {'page': {'$gt': 50} |
$lt | 小於 | |
$lte | 小於等於 | |
$gte | 大於等於 | |
$ne | 不等於 | |
$in | 在范圍內 | {'page': {'$in': [50, 100]}} |
$nin | 不在范圍內 | {'page': {'$nin': [50, 100]}} |
$regex | 匹配正則表達式 | {'name': {'$regex': '^張.*'}} |
$exists | 屬性是否存在 | {'name': {'$exists': True}} |
$type | 類型判斷 | {'name': {'$type': 'string'}} |
$mod | 數字模操作 | {'page': {'$mod': [80, 10]}} |
$text | 文本查詢 | {'$text': {'$search': 'Java'}} |
$where | 高級條件查詢 | {'$where': 'obj. author == obj. full_name'} |
數據的更新操作
更新操作和插入操作類似,PyMongo
提供了兩種更新方法,即 update_one()
和 update_many()
方法,其中 update_one()
方法只會更新滿足條件的第一條記錄。
注意:
- 如果使用 $set,則只更新 book 對象內存在的字段,如果更新前還有其他字段,則不更新也不刪除。
- 如果不使用 $set,則會把更新前的數據全部用 book 對象替換,如果原本存在其他字段則會被刪除。
# 查詢一條記錄
book = collection.find_one({'author': '張三'})
book['page'] = 90
# 更新滿足條件{'author', '張三'}的第一條記錄
res = collection.update_one({'author': '張三'}, {'$set': book})
# 更新返回結果是一個對象,我們可以調用matched_count和modified_count屬性分別獲得匹配的數據條數和影響的數據條數。
print(res.matched_count, res.modified_count)
#打印結果:1 1
# 更新滿足條件 page>90 的所有記錄,page 字段自加 10
res = collection.update_many({'page': {'$gt': 90}}, {'$inc': {'page': 10}})
# 打印更新匹配和影響的記錄數
print(res.matched_count, res.modified_count)
#打印結果:2 2
book3 = {'name':'Python高級', 'author':'趙飛', 'page': 50}
#upsert=True表示如果沒有滿足更新條件的記錄,則會將book3插入集合中
res = collection.update_one({'author': '趙飛'}, {'$set': book3}, upsert=True)
print(res.matched_count, res.modified_count)
#打印結果:0 0
# 查詢所有記錄,並遍歷打印出來
res = collection.find()
for r in res:
print(r)
#打印結果:
# {'_id': ObjectId('5de4c7b90ae08431839ac2a7'), 'name': 'Python基礎', 'author': '張三', 'page': 90}
# {'_id': ObjectId('5de4c8ae0ae08431839ac2a8'), 'name': 'Java基礎', 'author': '李白', 'page': 110}
# {'_id': ObjectId('5de4c8ae0ae08431839ac2a9'), 'name': 'Java虛擬機', 'author': '王五', 'page': 110}
# {'_id': ObjectId('5de4d76f71aa089d58170a92'), 'author': '趙飛', 'name': 'Python高級', 'page': 50}
集合的刪除操作
刪除數據同樣推薦使用兩個方法 delete_one()
和 delete_many()
,其中 delete_one()
為刪除第一條符合條件的記錄。具體操作代碼如下:
# 刪除滿足條件的第一條記錄
result = collection.delete_one({'author': '張三'})
# 同樣可以通過返回對象的 deleted_count 屬性查詢刪除的記錄數
print(result.deleted_count)
# 打印結果:1
# 刪除滿足條件的所有記錄,以下為刪除 page < 90 的記錄
result = collection.delete_many({'page': {'$lt': 90}})
print(result.deleted_count)
# 打印結果:1
其他數據庫操作
除了以上標准的數據庫操作外,PyMongo
還提供了以下通用且方便的操作方法,比如 limit()
方法用來讀取指定數量的數據
skip()
方法用來跳過指定數量的數據等,具體請看如下代碼:
# 查詢返回滿足條件的記錄然后刪除
result = collection.find_one_and_delete({'author': '王五'})
print(result)
# 打印結果:{'_id': ObjectId('5de4c8ae0ae08431839ac2a9'), 'name': 'Java虛擬機', 'author': '王五', 'page': 110}
# 統計查詢結果個數
# 全部結果個數
collection.find().count()
# 返回結果:1
# 滿足條件結果個數
collection.find({'page': 100}).count()
# 返回結果:0
# 查詢結果按字段排序
# 升序
results = collection.find().sort('page', ASCENDING)
# 降序
results = collection.find().sort('page', DESCENDING)
# 下面查詢結果是按page升序排序,只返回第二條記錄及以后的兩條結果
results = collection.find().sort('page', ASCENDING).skip(1).limit(2)
print(results)
注意:在數據量在在千萬、億級別龐大的時候,查詢時最好
skip()
的值不要太大,這樣很可能導致內存溢出。
數據索引操作
默認情況下,數據插入時已經有一個 _id
索引了,當然我們還可以創建自定義索引。
# unique=True時,創建一個唯一索引,索引字段插入相同值時會自動報錯,默認為False
collection.create_index('page', unique= True)
# 打印結果:'page_1'
# 打印出已創建的索引
print(collection.index_information())
# 返回結果:{'_id_': {'v': 2, 'key': [('_id', 1)], 'ns': 'testdb.test'}, 'page_1': {'v': 2, 'unique': True, 'key': [('page', 1)], 'ns': 'testdb.test'}}
# 刪除索引
collection.drop_index('page_1')
#刪除集合
collection.drop()
總結
本文為大家介紹了 Python 中如何創建連接 MongoDB 數據庫,並通過代碼的方式展示了對 MongoDB 數據的增刪改查以及排序索引等操作,通過以上學習個人感覺操作起來還是比較簡單方便的。今天就先介紹到這里,以后還會為大家介紹其他數據庫的操作。
參考
PyMongo 文檔:https://pymongo.readthedocs.io/en/stable/
關注公眾號:python技術,回復"python"一起學習交流