教程:基于python的MongoDB
總覽
MongoDB是數(shù)據(jù)科學(xué)家常用的一種非結(jié)構(gòu)化數(shù)據(jù)庫
本文我們討論如何使用Python(和PyMongo庫)來使用MongoDB數(shù)據(jù)庫。
本文我們使用Python實(shí)現(xiàn)對(duì)MongoDB數(shù)據(jù)庫的所有基本操作
結(jié)構(gòu)化數(shù)據(jù)庫面臨的挑戰(zhàn)
如今我們正在正以前所未有的速度產(chǎn)生數(shù)據(jù),這些數(shù)據(jù)的規(guī)模和大小令人難以置信!如下:
Facebook在一天之內(nèi)就生成了4PB的數(shù)據(jù)
Google每天產(chǎn)生20PB的數(shù)據(jù)
此外,大型強(qiáng)子對(duì)撞機(jī)(27公里長(zhǎng),是世界上功能最強(qiáng)大的粒子加速器)每秒可生成1PB的數(shù)據(jù)。最重要的是,這些數(shù)據(jù)是非結(jié)構(gòu)化的
如果使用SQL來處理這些大量數(shù)據(jù)會(huì)讓自己陷入噩夢(mèng)中!
SQL是作為數(shù)據(jù)科學(xué)家學(xué)習(xí)的一種很棒的語言,當(dāng)我們處理結(jié)構(gòu)化數(shù)據(jù)時(shí),它確實(shí)能很好地工作,但是,如果你使用非結(jié)構(gòu)化數(shù)據(jù),則SQL數(shù)據(jù)庫是無法滿足需求的。
結(jié)構(gòu)化數(shù)據(jù)庫有兩個(gè)主要缺點(diǎn):可擴(kuò)展性:隨著數(shù)據(jù)庫的擴(kuò)大,很難擴(kuò)展
彈性:結(jié)構(gòu)化數(shù)據(jù)庫需要預(yù)定義數(shù)據(jù)的格式,如果數(shù)據(jù)未遵循預(yù)定義的格式,則關(guān)系數(shù)據(jù)庫不會(huì)存儲(chǔ)該數(shù)據(jù)
那么我們?nèi)绾谓鉀Q這個(gè)問題呢?如果不用SQL,那又怎么解決這些問題?
這就是我們用到非結(jié)構(gòu)化數(shù)據(jù)庫的地方了。在廣泛的數(shù)據(jù)庫中,MongoDB因其豐富的查詢語言和對(duì)索引等概念的快速訪問而被廣泛使用。簡(jiǎn)而言之,MongoDB最適合管理大數(shù)據(jù)。讓我們看看結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)庫之間的區(qū)別:
目錄
什么是MongoDB?
MongoDB數(shù)據(jù)庫的架構(gòu)
了解問題陳述
什么是PyMongo?
MongoDB安裝指南
MongoDB數(shù)據(jù)庫的基本操作
連接到數(shù)據(jù)庫
檢索/獲取數(shù)據(jù)
插入
過濾條件
刪除
創(chuàng)建數(shù)據(jù)庫和集合
將獲取的數(shù)據(jù)轉(zhuǎn)換為結(jié)構(gòu)化形式
存儲(chǔ)到DataFrame
寫入文件。
其他有用的功能
1.什么是MongoDB?
MongoDB是一個(gè)非結(jié)構(gòu)化數(shù)據(jù)庫,它以文檔形式存儲(chǔ)數(shù)據(jù)。MongoDB能夠非常高效地處理大量數(shù)據(jù)。因?yàn)樗峁┝素S富的查詢語言以及對(duì)數(shù)據(jù)的靈活而快速的訪問,所以MongoDB是使用最廣泛的NoSQL數(shù)據(jù)庫。
在進(jìn)入本教程的重點(diǎn)之前,讓我們花一點(diǎn)時(shí)間來了解MongoDB數(shù)據(jù)庫的體系結(jié)構(gòu)。
MongoDB數(shù)據(jù)庫的架構(gòu)
MongoDB中的信息存儲(chǔ)在文檔中,這里文檔類似于結(jié)構(gòu)化數(shù)據(jù)庫中的行。
每個(gè)文檔都是鍵值對(duì)的集合
每個(gè)鍵值對(duì)稱為一個(gè)字段
每個(gè)文檔都有一個(gè)_id 字段,用于唯一標(biāo)識(shí)文檔
文檔也可以包含嵌套文檔
文檔可以具有不同數(shù)量的字段(它們也可以為空白)
這些文檔存儲(chǔ)在一個(gè)集合中。集合實(shí)際上是MongoDB中文檔的集合,這類似于傳統(tǒng)數(shù)據(jù)庫中的表。
與傳統(tǒng)數(shù)據(jù)庫不同,MongoDB的數(shù)據(jù)通常存儲(chǔ)在MongoDB中的單個(gè)集合中,因此沒有連接的概念($lookup運(yùn)算符除外,該運(yùn)算符執(zhí)行左外聯(lián)接之類的操作)。MongoDB擁有嵌套文檔。
2.了解問題陳述讓我們了解會(huì)在本教程中解決的問題,這會(huì)使你對(duì)可以對(duì)MongoDB實(shí)踐有一個(gè)更好的了解,以進(jìn)一步磨練MongoDB的Python技能。
假設(shè)你正在為一個(gè)向客戶提供一個(gè)銀行系統(tǒng)的應(yīng)用程序,該應(yīng)用程序?qū)?shù)據(jù)發(fā)送到你的MongoDB數(shù)據(jù)庫中。此數(shù)據(jù)存儲(chǔ)在三個(gè)集合中:
accounts集合-包含有關(guān)所有帳戶的信息
customers集合-包含有關(guān)客戶的信息
transactions集合-包含客戶事務(wù)數(shù)據(jù)
我已從全球云數(shù)據(jù)庫服務(wù)MongoDB Atlas取得了本教程的示例數(shù)據(jù)庫。
我們將使用“ sample_analytics”數(shù)據(jù)庫來處理上述的問題,該數(shù)據(jù)庫包含與金融服務(wù)有關(guān)的數(shù)據(jù)。
3.什么是PyMongo?
PyMongo是一個(gè)Python庫,使我們能夠與MongoDB連接,以及使我們能夠?qū)ongoDB數(shù)據(jù)庫執(zhí)行基本操作。
那么,為什么要使用Python?
我們選擇Python與MongoDB進(jìn)行交互是因?yàn)樗菙?shù)據(jù)科學(xué)中最常用且功能最強(qiáng)大的語言之一。PyMongo允許我們使用類似于字典的語法來檢索數(shù)據(jù)。
同時(shí)我們還可以使用點(diǎn)表示法來訪問MongoDB數(shù)據(jù),它簡(jiǎn)單的語法使我們的工作變得容易得多,此外PyMongo有豐富的幫助文檔。我們使用該庫來訪問MongoDB。
4. MongoDB安裝指南
MongoDB可用于Linux,Windows和Mac OS X操作系統(tǒng)。
安裝數(shù)據(jù)庫后,需要啟動(dòng)mongod 服務(wù)。如果你在安裝過程中遇到任何問題,可以隨時(shí)在本文下面的評(píng)論部分與我聯(lián)系。
5. MongoDB數(shù)據(jù)庫的基本操作現(xiàn)在我們對(duì)MongoDB已經(jīng)有了一個(gè)很好的概念——讓我們把這些知識(shí)付諸行動(dòng)吧。
我們將使用PyMongo庫對(duì)Python中的MongoDB數(shù)據(jù)庫執(zhí)行一些關(guān)鍵的基本操作。
5.1連接到數(shù)據(jù)庫
要從MongoDB數(shù)據(jù)庫檢索數(shù)據(jù),我們將首先需要連接到它。在Jupyter單元中編寫并執(zhí)行以下代碼,以連接到MongoDB:import pymongo
import pprint
mongo_uri = "mongodb://localhost:27017/"
client = pymongo.MongoClient(mongo_uri)
讓我們看看可用的數(shù)據(jù)庫:client.list_database_names()
我們將使用sample_analytics數(shù)據(jù)庫來實(shí)現(xiàn)我們的目的,讓我們將游標(biāo)設(shè)置為相同的數(shù)據(jù)庫:db = client.sample_analytics
該list_collection_names命令顯示所有可用的集合名稱:db.list_collection_names()
讓我們看看我們有多少客戶。我們將連接到客戶集合,然后打印該集合中可用的文檔數(shù)量:table=db.customers
table.count_documents({}) #gives the number of documents in the table
輸出:500在這里,我們可以看到有500個(gè)客戶的數(shù)據(jù)。接下來,我們將從該表中獲取MongoDB文檔,并查看那里提供了哪些信息。5.2 檢索/獲取數(shù)據(jù)我們可以使用類似字典符號(hào)或PyMongo中的點(diǎn)運(yùn)算符來查詢MongoDB。在上一節(jié)中,我們使用了點(diǎn)運(yùn)算符來訪問MongoDB數(shù)據(jù)庫,在這里,我們使用類似字典的語法進(jìn)行演示。首先,讓我們從MongoDB集合中獲取一個(gè)文檔,我們?yōu)榇耸褂胒ind_one函數(shù):table.find_one()
我們可以看到該函數(shù)返回了一個(gè)字典。讓我們看一下該字典的鍵。first_instance.keys()
我們可以看到一些鍵是不言自明的,讓我解釋一下每個(gè)密鑰存儲(chǔ)的內(nèi)容:_id:MongoDB為每個(gè)文檔分配一個(gè)唯一的IDusername :包含用戶的用戶名name:用戶名address:用戶的地址存儲(chǔ)在此字段中birthdate:此參數(shù)存儲(chǔ)用戶的出生日期email:這是給定用戶的電子郵件IDactive:此字段告訴用戶是否活躍address:它存儲(chǔ)給定用戶擁有的所有帳戶列表,一個(gè)用戶可以有多個(gè)帳戶teir_and_details:類別(銀,金等)存儲(chǔ)在此參數(shù)中,該字段還存儲(chǔ)他們有權(quán)獲得的利益現(xiàn)在,讓我們看一下MongoDB的字典式訪問示例。讓我們從MongoDB文檔中獲取客戶的名稱:first_instance['name']
我們還可以使用find函數(shù)來獲取文檔,find_one一次僅獲取一個(gè)文檔,另一方面,find可以從MongoDB集合中獲取多個(gè)文檔:table.find().sort("_id",pymongo.DESCENDING)
在此,sort函數(shù)以_id的降序?qū)ξ臋n進(jìn)行排序。5.3插入功能insert_one函數(shù)可用于一次在MongoDB中插入一個(gè)文檔。我們首先創(chuàng)建一個(gè)字典,然后將其插入MongoDB數(shù)據(jù)庫中:post = {"_id": 'qwertyui123456',
'username': 'someone',
'name':'Gyan',
'address':'Somewhere in India'}
post_id = table.insert_one(post).inserted_id
post_id
輸出:qwertyui123456MongoDB是一個(gè)非結(jié)構(gòu)化數(shù)據(jù)庫,因此集合中的所有文檔都不必遵循相同的結(jié)構(gòu)。例如,在上述情況下插入的字典不包含我們?cè)谙惹矮@取的MongoDB文檔中看到的一些字段。.inserted_id提供了默認(rèn)分配的 _id字段(如果字典中未提供它)。就我們而言,我們已明確提供了該字段,最后,該操作返回插入的MongoDB文檔的 _id。在上述情況下,它存儲(chǔ)在 post_id變量中。到目前為止,我們實(shí)現(xiàn)了在MongoDB集合中插入一個(gè)文檔。如果必須一次插入數(shù)千個(gè)文檔,該怎么辦?為解決這個(gè)問題,我們引入insert_many函數(shù):import datetime
new_posts = [{"name": "Mike",
"username": "latestpost!",
"date": datetime.datetime(2009, 11, 12, 11, 14)},
{"name": "Eliot",
"title": "onceAgain",
"text": "and pretty easy too!",
"date": datetime.datetime(2009, 11, 10, 10, 45)}]
final = table.insert_many(new_posts)
final.inserted_ids
我們導(dǎo)入了datetime庫,因?yàn)镻ython中沒有內(nèi)置的日期和時(shí)間數(shù)據(jù)類型,該庫可以幫助我們分配datetime類型的值。在上述情況下,我們?cè)贛ongoDB數(shù)據(jù)庫中插入了詞典列表,每個(gè)元素都作為獨(dú)立文檔插入MongoDB集合中。5.4過濾條件我們已經(jīng)看到了如何使用find和find_one函數(shù)從MongoDB中獲取數(shù)據(jù),但是,在某些場(chǎng)景下,我們不需要獲取所有的文檔信息,所以我們需要用到過濾條件來過濾文檔。之前,我們?cè)贛ongoDB集合中插入了一個(gè)名為Gyan的文檔,現(xiàn)在讓我們看看如何使用篩選條件獲取MongoDB文檔:table.find_one({"name":'Gyan'})
在這里,我們使用一個(gè)字符串參數(shù)name來獲取文檔。另一方面,我們?cè)谇懊娴睦又锌吹搅薴inal,nserted_id包含插入文檔的id。如果我們對(duì) _id字段應(yīng)用篩選條件,它將不返回任何內(nèi)容,因?yàn)樗鼈兊臄?shù)據(jù)類型是ObjectId,這不是內(nèi)置數(shù)據(jù)類型。我們需要將字符串值轉(zhuǎn)換為ObjectId類型,以便對(duì) _id 應(yīng)用篩選條件。首先,我們將定義一個(gè)函數(shù)來轉(zhuǎn)換字符串值,然后獲取MongoDB文檔:from bson.objectid import ObjectId
post_id=final.inserted_ids[0]
def parser(post_id):
document = table.find_one({'_id': ObjectId(post_id)})
return document
parser(post_id)
5.5 刪除delete_one函數(shù)從MongoDB集合中刪除單個(gè)文件。上文我們是為名為Mike的用戶插入文檔的。讓我們看一下插入的MongoDB文檔:table.find_one({'name':'Mike'})
現(xiàn)在,我們將刪除此MongoDB文檔:table.delete_one({'name':'Mike'})
讓我們嘗試在刪除后獲取此文檔,如果我們的MongoDB集合中沒有此文檔,則find_one函數(shù)將不返回任何內(nèi)容。table.find_one({'name':'Mike'})
輸出:不返回任何內(nèi)容。由于我們沒有得到任何回復(fù)信息,這意味著MongoDB文檔不再存在。正如我們看到的,insert_many函數(shù)用于在MongoDB集合中插入多個(gè)文檔,delete_many用于一次刪除多個(gè)文檔。讓我們嘗試通過名稱字段刪除兩個(gè)MongoDB文檔:myquery = ({ "name":{"$in": ["Gyan","Eliot"]}})
x = table.delete_many(myquery)
print(x.deleted_count, " documents deleted.")
在此,deleted count存儲(chǔ)操作期間刪除的MongoDB文檔的數(shù)量。'$in'是MongoDB中的一個(gè)運(yùn)算符。5.6 創(chuàng)建數(shù)據(jù)庫和集合在MongoDB中,創(chuàng)建任何數(shù)據(jù)庫和集合都是一個(gè)非常簡(jiǎn)單的過程,你可以使用檢索語法來做到這一點(diǎn),如果你嘗試訪問一個(gè)不存在的數(shù)據(jù)庫,MongoDB將為你創(chuàng)建它。讓我們創(chuàng)建一個(gè)數(shù)據(jù)庫和一個(gè)集合:mydb=client.testDB
mycoll=mydb.testColl
已經(jīng)在此處創(chuàng)建了MongoDB數(shù)據(jù)庫,但是如果我們運(yùn)行l(wèi)ist_database_names,則不會(huì)列出該數(shù)據(jù)庫,因?yàn)镸ongoDB不顯示空數(shù)據(jù)庫,因此,我們將不得不在其中插入一些內(nèi)容。讓我們?cè)贛ongoDB集合中插入一個(gè)文檔:testInsert=mycoll.insert_one({"country":'India'}).inserted_id
client.list_database_names()
現(xiàn)在我們可以看到我們的數(shù)據(jù)庫在MongoDB數(shù)據(jù)庫列表中是可用的。6.將非結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)換為結(jié)構(gòu)化形式作為數(shù)據(jù)科學(xué)家,你不僅需要獲取數(shù)據(jù),還需要對(duì)其進(jìn)行分析。以結(jié)構(gòu)化形式存儲(chǔ)數(shù)據(jù)可簡(jiǎn)化此任務(wù)。在本節(jié)中,我們將學(xué)習(xí)如何將從MongoDB中獲取的數(shù)據(jù)轉(zhuǎn)換為結(jié)構(gòu)化格式。6.1存儲(chǔ)到DataFrame中find函數(shù)從MongoDB集合返回字典,你可以將其直接插入DataFrame。首先,讓我們獲取100個(gè)MongoDB文檔,然后將這些文檔存儲(chǔ)到一個(gè)DataFrame中:import pandas as pd
samples=table.find().sort("_id",pymongo.DESCENDING)[:100]
df=pd.DataFrame(samples)
df.head()
該DataFrame的可讀性遠(yuǎn)遠(yuǎn)優(yōu)于該函數(shù)返回的默認(rèn)格式。
6.2寫入文件Pandas DataFrame可以直接導(dǎo)出為CSV,Excel或SQL。
讓我們嘗試將這些數(shù)據(jù)存儲(chǔ)到CSV文件中:Pandas
同樣,你可以使用to_sql函數(shù)將數(shù)據(jù)導(dǎo)出到SQL數(shù)據(jù)庫。
7.其他一些有用的MongoDB函數(shù)你已經(jīng)積累了足夠的知識(shí)來開始使用MongoDB了,到目前為止,我們已經(jīng)通過示例討論了所有基本操作,同時(shí)我們還了解了MongoDB的幾個(gè)理論概念。在完成本文之前,讓我分享一些PyMongo的有用功能:sort:我們已經(jīng)看到了此功能的示例,此功能的目的是對(duì)文檔進(jìn)行排序limit:此函數(shù)限制由find函數(shù)獲取的MongoDB文檔的數(shù)量
8. 接下來是什么?掌握了本教程中介紹的概念之后,你應(yīng)該學(xué)習(xí)與MongoDB相關(guān)的更高級(jí)的主題,如下:索引:索引是在MongoDB中對(duì)集合的某些屬性(字段)創(chuàng)建索引的過程,它使檢索過程更快。在沒有索引的集合中,當(dāng)你嘗試根據(jù)字段的給定條件篩選出特定文檔時(shí),它將掃描整個(gè)數(shù)據(jù)庫。如果有數(shù)以億計(jì)的文檔,這個(gè)過程需要時(shí)間。
索引之后,MongoDB使用大量?jī)?nèi)存來存儲(chǔ)索引信息,此索引允許你根據(jù)篩選條件跳轉(zhuǎn)到特定文檔,而無需掃描整個(gè)數(shù)據(jù)庫分片:跨多臺(tái)機(jī)器存儲(chǔ)數(shù)據(jù)的過程稱為分片,分片有助于數(shù)據(jù)庫的水平擴(kuò)展運(yùn)算符:我們已經(jīng)在MongoDB中看到了$in操作符,還有一些其他有用的運(yùn)算符可以執(zhí)行某些特定的功能結(jié)尾在本文中,我們學(xué)習(xí)了MongoDB的所有基本概念,這足以讓你在非結(jié)構(gòu)化數(shù)據(jù)庫的學(xué)習(xí)上有一個(gè)堅(jiān)實(shí)的開端。

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
6月20日立即下載>> 【白皮書】精準(zhǔn)測(cè)量 安全高效——福祿克光伏行業(yè)解決方案
-
7月3日立即報(bào)名>> 【在線會(huì)議】英飛凌新一代智能照明方案賦能綠色建筑與工業(yè)互聯(lián)
-
7月22-29日立即報(bào)名>> 【線下論壇】第三屆安富利汽車生態(tài)圈峰會(huì)
-
7.30-8.1火熱報(bào)名中>> 全數(shù)會(huì)2025(第六屆)機(jī)器人及智能工廠展
-
7月31日免費(fèi)預(yù)約>> OFweek 2025具身機(jī)器人動(dòng)力電池技術(shù)應(yīng)用大會(huì)
-
免費(fèi)參會(huì)立即報(bào)名>> 7月30日- 8月1日 2025全數(shù)會(huì)工業(yè)芯片與傳感儀表展
推薦專題
- 1 AI 眼鏡讓百萬 APP「集體失業(yè)」?
- 2 大廠紛紛入局,百度、阿里、字節(jié)搶奪Agent話語權(quán)
- 3 深度報(bào)告|中國(guó)AI產(chǎn)業(yè)正在崛起成全球力量,市場(chǎng)潛力和關(guān)鍵挑戰(zhàn)有哪些?
- 4 上海跑出80億超級(jí)獨(dú)角獸:獲上市公司戰(zhàn)投,干人形機(jī)器人
- 5 國(guó)家數(shù)據(jù)局局長(zhǎng)劉烈宏調(diào)研格創(chuàng)東智
- 6 一文看懂視覺語言動(dòng)作模型(VLA)及其應(yīng)用
- 7 下一代入口之戰(zhàn):大廠為何紛紛押注智能體?
- 8 百億AI芯片訂單,瘋狂傾銷中東?
- 9 Robotaxi新消息密集釋放,量產(chǎn)元年誰在領(lǐng)跑?
- 10 格斗大賽出圈!人形機(jī)器人致命短板曝光:頭腦過于簡(jiǎn)單