教程:基于python的MongoDB
總覽
MongoDB是數(shù)據(jù)科學(xué)家常用的一種非結(jié)構(gòu)化數(shù)據(jù)庫
本文我們討論如何使用Python(和PyMongo庫)來使用MongoDB數(shù)據(jù)庫。
本文我們使用Python實(shí)現(xiàn)對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)子對撞機(jī)(27公里長,是世界上功能最強(qiáng)大的粒子加速器)每秒可生成1PB的數(shù)據(jù)。最重要的是,這些數(shù)據(jù)是非結(jié)構(gòu)化的
如果使用SQL來處理這些大量數(shù)據(jù)會讓自己陷入噩夢中!
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ù)庫不會存儲該數(shù)據(jù)
那么我們?nèi)绾谓鉀Q這個(gè)問題呢?如果不用SQL,那又怎么解決這些問題?
這就是我們用到非結(jié)構(gòu)化數(shù)據(jù)庫的地方了。在廣泛的數(shù)據(jù)庫中,MongoDB因其豐富的查詢語言和對索引等概念的快速訪問而被廣泛使用。簡而言之,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)化形式
存儲到DataFrame
寫入文件。
其他有用的功能
1.什么是MongoDB?
MongoDB是一個(gè)非結(jié)構(gòu)化數(shù)據(jù)庫,它以文檔形式存儲數(shù)據(jù)。MongoDB能夠非常高效地處理大量數(shù)據(jù)。因?yàn)樗峁┝素S富的查詢語言以及對數(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中的信息存儲在文檔中,這里文檔類似于結(jié)構(gòu)化數(shù)據(jù)庫中的行。
每個(gè)文檔都是鍵值對的集合
每個(gè)鍵值對稱為一個(gè)字段
每個(gè)文檔都有一個(gè)_id 字段,用于唯一標(biāo)識文檔
文檔也可以包含嵌套文檔
文檔可以具有不同數(shù)量的字段(它們也可以為空白)
這些文檔存儲在一個(gè)集合中。集合實(shí)際上是MongoDB中文檔的集合,這類似于傳統(tǒng)數(shù)據(jù)庫中的表。
與傳統(tǒng)數(shù)據(jù)庫不同,MongoDB的數(shù)據(jù)通常存儲在MongoDB中的單個(gè)集合中,因此沒有連接的概念($lookup運(yùn)算符除外,該運(yùn)算符執(zhí)行左外聯(lián)接之類的操作)。MongoDB擁有嵌套文檔。
2.了解問題陳述讓我們了解會在本教程中解決的問題,這會使你對可以對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ù)存儲在三個(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ù),它簡單的語法使我們的工作變得容易得多,此外PyMongo有豐富的幫助文檔。我們使用該庫來訪問MongoDB。
4. MongoDB安裝指南
MongoDB可用于Linux,Windows和Mac OS X操作系統(tǒng)。
安裝數(shù)據(jù)庫后,需要啟動(dòng)mongod 服務(wù)。如果你在安裝過程中遇到任何問題,可以隨時(shí)在本文下面的評論部分與我聯(lián)系。
5. MongoDB數(shù)據(jù)庫的基本操作現(xiàn)在我們對MongoDB已經(jīng)有了一個(gè)很好的概念——讓我們把這些知識付諸行動(dòng)吧。
我們將使用PyMongo庫對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ù)我們可以使用類似字典符號或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è)密鑰存儲的內(nèi)容:_id:MongoDB為每個(gè)文檔分配一個(gè)唯一的IDusername :包含用戶的用戶名name:用戶名address:用戶的地址存儲在此字段中birthdate:此參數(shù)存儲用戶的出生日期email:這是給定用戶的電子郵件IDactive:此字段告訴用戶是否活躍address:它存儲給定用戶擁有的所有帳戶列表,一個(gè)用戶可以有多個(gè)帳戶teir_and_details:類別(銀,金等)存儲在此參數(shù)中,該字段還存儲他們有權(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)。例如,在上述情況下插入的字典不包含我們在先前獲取的MongoDB文檔中看到的一些字段。.inserted_id提供了默認(rèn)分配的 _id字段(如果字典中未提供它)。就我們而言,我們已明確提供了該字段,最后,該操作返回插入的MongoDB文檔的 _id。在上述情況下,它存儲在 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類型的值。在上述情況下,我們在MongoDB數(shù)據(jù)庫中插入了詞典列表,每個(gè)元素都作為獨(dú)立文檔插入MongoDB集合中。5.4過濾條件我們已經(jīng)看到了如何使用find和find_one函數(shù)從MongoDB中獲取數(shù)據(jù),但是,在某些場景下,我們不需要獲取所有的文檔信息,所以我們需要用到過濾條件來過濾文檔。之前,我們在MongoDB集合中插入了一個(gè)名為Gyan的文檔,現(xiàn)在讓我們看看如何使用篩選條件獲取MongoDB文檔:table.find_one({"name":'Gyan'})
在這里,我們使用一個(gè)字符串參數(shù)name來獲取文檔。另一方面,我們在前面的例子中看到了final,nserted_id包含插入文檔的id。如果我們對 _id字段應(yīng)用篩選條件,它將不返回任何內(nèi)容,因?yàn)樗鼈兊臄?shù)據(jù)類型是ObjectId,這不是內(nèi)置數(shù)據(jù)類型。我們需要將字符串值轉(zhuǎn)換為ObjectId類型,以便對 _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存儲操作期間刪除的MongoDB文檔的數(shù)量。'$in'是MongoDB中的一個(gè)運(yùn)算符。5.6 創(chuàng)建數(shù)據(jù)庫和集合在MongoDB中,創(chuàng)建任何數(shù)據(jù)庫和集合都是一個(gè)非常簡單的過程,你可以使用檢索語法來做到這一點(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,則不會列出該數(shù)據(jù)庫,因?yàn)镸ongoDB不顯示空數(shù)據(jù)庫,因此,我們將不得不在其中插入一些內(nèi)容。讓我們在MongoDB集合中插入一個(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ù),還需要對其進(jìn)行分析。以結(jié)構(gòu)化形式存儲數(shù)據(jù)可簡化此任務(wù)。在本節(jié)中,我們將學(xué)習(xí)如何將從MongoDB中獲取的數(shù)據(jù)轉(zhuǎn)換為結(jié)構(gòu)化格式。6.1存儲到DataFrame中find函數(shù)從MongoDB集合返回字典,你可以將其直接插入DataFrame。首先,讓我們獲取100個(gè)MongoDB文檔,然后將這些文檔存儲到一個(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ù)存儲到CSV文件中:Pandas
同樣,你可以使用to_sql函數(shù)將數(shù)據(jù)導(dǎo)出到SQL數(shù)據(jù)庫。
7.其他一些有用的MongoDB函數(shù)你已經(jīng)積累了足夠的知識來開始使用MongoDB了,到目前為止,我們已經(jīng)通過示例討論了所有基本操作,同時(shí)我們還了解了MongoDB的幾個(gè)理論概念。在完成本文之前,讓我分享一些PyMongo的有用功能:sort:我們已經(jīng)看到了此功能的示例,此功能的目的是對文檔進(jìn)行排序limit:此函數(shù)限制由find函數(shù)獲取的MongoDB文檔的數(shù)量
8. 接下來是什么?掌握了本教程中介紹的概念之后,你應(yīng)該學(xué)習(xí)與MongoDB相關(guān)的更高級的主題,如下:索引:索引是在MongoDB中對集合的某些屬性(字段)創(chuàng)建索引的過程,它使檢索過程更快。在沒有索引的集合中,當(dāng)你嘗試根據(jù)字段的給定條件篩選出特定文檔時(shí),它將掃描整個(gè)數(shù)據(jù)庫。如果有數(shù)以億計(jì)的文檔,這個(gè)過程需要時(shí)間。
索引之后,MongoDB使用大量內(nèi)存來存儲索引信息,此索引允許你根據(jù)篩選條件跳轉(zhuǎn)到特定文檔,而無需掃描整個(gè)數(shù)據(jù)庫分片:跨多臺機(jī)器存儲數(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í)的開端。

請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個(gè)字
最新活動(dòng)更多
-
3月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會
-
4月30日立即下載>> 【村田汽車】汽車E/E架構(gòu)革新中,新智能座艙挑戰(zhàn)的解決方案
-
5月15-17日立即預(yù)約>> 【線下巡回】2025年STM32峰會
-
即日-5.15立即報(bào)名>>> 【在線會議】安森美Hyperlux™ ID系列引領(lǐng)iToF技術(shù)革新
-
5月15日立即下載>> 【白皮書】精確和高效地表征3000V/20A功率器件應(yīng)用指南
-
5月16日立即參評 >> 【評選啟動(dòng)】維科杯·OFweek 2025(第十屆)人工智能行業(yè)年度評選
推薦專題
-
10 月之暗面,絕地反擊
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達(dá)AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 “AI寒武紀(jì)”爆發(fā)至今,五類新物種登上歷史舞臺
- 4 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 5 國產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計(jì)算迎來商業(yè)化突破,但落地仍需時(shí)間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 地平線自動(dòng)駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機(jī)器人東風(fēng)翻身?