教程:基于python的MongoDB
總覽
MongoDB是數(shù)據(jù)科學(xué)家常用的一種非結(jié)構(gòu)化數(shù)據(jù)庫
本文我們討論如何使用Python(和PyMongo庫)來使用MongoDB數(shù)據(jù)庫。
本文我們使用Python實現(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ù)
此外,大型強子對撞機(27公里長,是世界上功能最強大的粒子加速器)每秒可生成1PB的數(shù)據(jù)。最重要的是,這些數(shù)據(jù)是非結(jié)構(gòu)化的
如果使用SQL來處理這些大量數(shù)據(jù)會讓自己陷入噩夢中!
SQL是作為數(shù)據(jù)科學(xué)家學(xué)習的一種很棒的語言,當我們處理結(jié)構(gòu)化數(shù)據(jù)時,它確實能很好地工作,但是,如果你使用非結(jié)構(gòu)化數(shù)據(jù),則SQL數(shù)據(jù)庫是無法滿足需求的。
結(jié)構(gòu)化數(shù)據(jù)庫有兩個主要缺點:可擴展性:隨著數(shù)據(jù)庫的擴大,很難擴展
彈性:結(jié)構(gòu)化數(shù)據(jù)庫需要預(yù)定義數(shù)據(jù)的格式,如果數(shù)據(jù)未遵循預(yù)定義的格式,則關(guān)系數(shù)據(jù)庫不會存儲該數(shù)據(jù)
那么我們?nèi)绾谓鉀Q這個問題呢?如果不用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是一個非結(jié)構(gòu)化數(shù)據(jù)庫,它以文檔形式存儲數(shù)據(jù)。MongoDB能夠非常高效地處理大量數(shù)據(jù)。因為它提供了豐富的查詢語言以及對數(shù)據(jù)的靈活而快速的訪問,所以MongoDB是使用最廣泛的NoSQL數(shù)據(jù)庫。
在進入本教程的重點之前,讓我們花一點時間來了解MongoDB數(shù)據(jù)庫的體系結(jié)構(gòu)。
MongoDB數(shù)據(jù)庫的架構(gòu)
MongoDB中的信息存儲在文檔中,這里文檔類似于結(jié)構(gòu)化數(shù)據(jù)庫中的行。
每個文檔都是鍵值對的集合
每個鍵值對稱為一個字段
每個文檔都有一個_id 字段,用于唯一標識文檔
文檔也可以包含嵌套文檔
文檔可以具有不同數(shù)量的字段(它們也可以為空白)
這些文檔存儲在一個集合中。集合實際上是MongoDB中文檔的集合,這類似于傳統(tǒng)數(shù)據(jù)庫中的表。
與傳統(tǒng)數(shù)據(jù)庫不同,MongoDB的數(shù)據(jù)通常存儲在MongoDB中的單個集合中,因此沒有連接的概念($lookup運算符除外,該運算符執(zhí)行左外聯(lián)接之類的操作)。MongoDB擁有嵌套文檔。
2.了解問題陳述讓我們了解會在本教程中解決的問題,這會使你對可以對MongoDB實踐有一個更好的了解,以進一步磨練MongoDB的Python技能。
假設(shè)你正在為一個向客戶提供一個銀行系統(tǒng)的應(yīng)用程序,該應(yīng)用程序?qū)?shù)據(jù)發(fā)送到你的MongoDB數(shù)據(jù)庫中。此數(shù)據(jù)存儲在三個集合中:
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是一個Python庫,使我們能夠與MongoDB連接,以及使我們能夠?qū)ongoDB數(shù)據(jù)庫執(zhí)行基本操作。
那么,為什么要使用Python?
我們選擇Python與MongoDB進行交互是因為它是數(shù)據(jù)科學(xué)中最常用且功能最強大的語言之一。PyMongo允許我們使用類似于字典的語法來檢索數(shù)據(jù)。
同時我們還可以使用點表示法來訪問MongoDB數(shù)據(jù),它簡單的語法使我們的工作變得容易得多,此外PyMongo有豐富的幫助文檔。我們使用該庫來訪問MongoDB。
4. MongoDB安裝指南
MongoDB可用于Linux,Windows和Mac OS X操作系統(tǒng)。
安裝數(shù)據(jù)庫后,需要啟動mongod 服務(wù)。如果你在安裝過程中遇到任何問題,可以隨時在本文下面的評論部分與我聯(lián)系。
5. MongoDB數(shù)據(jù)庫的基本操作現(xiàn)在我們對MongoDB已經(jī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ù)庫來實現(xiàn)我們的目的,讓我們將游標設(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個客戶的數(shù)據(jù)。接下來,我們將從該表中獲取MongoDB文檔,并查看那里提供了哪些信息。5.2 檢索/獲取數(shù)據(jù)我們可以使用類似字典符號或PyMongo中的點運算符來查詢MongoDB。在上一節(jié)中,我們使用了點運算符來訪問MongoDB數(shù)據(jù)庫,在這里,我們使用類似字典的語法進行演示。首先,讓我們從MongoDB集合中獲取一個文檔,我們?yōu)榇耸褂胒ind_one函數(shù):table.find_one()
我們可以看到該函數(shù)返回了一個字典。讓我們看一下該字典的鍵。first_instance.keys()
我們可以看到一些鍵是不言自明的,讓我解釋一下每個密鑰存儲的內(nèi)容:_id:MongoDB為每個文檔分配一個唯一的IDusername :包含用戶的用戶名name:用戶名address:用戶的地址存儲在此字段中birthdate:此參數(shù)存儲用戶的出生日期email:這是給定用戶的電子郵件IDactive:此字段告訴用戶是否活躍address:它存儲給定用戶擁有的所有帳戶列表,一個用戶可以有多個帳戶teir_and_details:類別(銀,金等)存儲在此參數(shù)中,該字段還存儲他們有權(quán)獲得的利益現(xiàn)在,讓我們看一下MongoDB的字典式訪問示例。讓我們從MongoDB文檔中獲取客戶的名稱:first_instance['name']
我們還可以使用find函數(shù)來獲取文檔,find_one一次僅獲取一個文檔,另一方面,find可以從MongoDB集合中獲取多個文檔:table.find().sort("_id",pymongo.DESCENDING)
在此,sort函數(shù)以_id的降序?qū)ξ臋n進行排序。5.3插入功能insert_one函數(shù)可用于一次在MongoDB中插入一個文檔。我們首先創(chuàng)建一個字典,然后將其插入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是一個非結(jié)構(gòu)化數(shù)據(jù)庫,因此集合中的所有文檔都不必遵循相同的結(jié)構(gòu)。例如,在上述情況下插入的字典不包含我們在先前獲取的MongoDB文檔中看到的一些字段。.inserted_id提供了默認分配的 _id字段(如果字典中未提供它)。就我們而言,我們已明確提供了該字段,最后,該操作返回插入的MongoDB文檔的 _id。在上述情況下,它存儲在 post_id變量中。到目前為止,我們實現(xiàn)了在MongoDB集合中插入一個文檔。如果必須一次插入數(shù)千個文檔,該怎么辦?為解決這個問題,我們引入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庫,因為Python中沒有內(nèi)置的日期和時間數(shù)據(jù)類型,該庫可以幫助我們分配datetime類型的值。在上述情況下,我們在MongoDB數(shù)據(jù)庫中插入了詞典列表,每個元素都作為獨立文檔插入MongoDB集合中。5.4過濾條件我們已經(jīng)看到了如何使用find和find_one函數(shù)從MongoDB中獲取數(shù)據(jù),但是,在某些場景下,我們不需要獲取所有的文檔信息,所以我們需要用到過濾條件來過濾文檔。之前,我們在MongoDB集合中插入了一個名為Gyan的文檔,現(xiàn)在讓我們看看如何使用篩選條件獲取MongoDB文檔:table.find_one({"name":'Gyan'})
在這里,我們使用一個字符串參數(shù)name來獲取文檔。另一方面,我們在前面的例子中看到了final,nserted_id包含插入文檔的id。如果我們對 _id字段應(yīng)用篩選條件,它將不返回任何內(nèi)容,因為它們的數(shù)據(jù)類型是ObjectId,這不是內(nèi)置數(shù)據(jù)類型。我們需要將字符串值轉(zhuǎn)換為ObjectId類型,以便對 _id 應(yīng)用篩選條件。首先,我們將定義一個函數(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集合中刪除單個文件。上文我們是為名為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集合中插入多個文檔,delete_many用于一次刪除多個文檔。讓我們嘗試通過名稱字段刪除兩個MongoDB文檔:myquery = ({ "name":{"$in": ["Gyan","Eliot"]}})
x = table.delete_many(myquery)
print(x.deleted_count, " documents deleted.")
在此,deleted count存儲操作期間刪除的MongoDB文檔的數(shù)量。'$in'是MongoDB中的一個運算符。5.6 創(chuàng)建數(shù)據(jù)庫和集合在MongoDB中,創(chuàng)建任何數(shù)據(jù)庫和集合都是一個非常簡單的過程,你可以使用檢索語法來做到這一點,如果你嘗試訪問一個不存在的數(shù)據(jù)庫,MongoDB將為你創(chuàng)建它。讓我們創(chuàng)建一個數(shù)據(jù)庫和一個集合:mydb=client.testDB
mycoll=mydb.testColl
已經(jīng)在此處創(chuàng)建了MongoDB數(shù)據(jù)庫,但是如果我們運行l(wèi)ist_database_names,則不會列出該數(shù)據(jù)庫,因為MongoDB不顯示空數(shù)據(jù)庫,因此,我們將不得不在其中插入一些內(nèi)容。讓我們在MongoDB集合中插入一個文檔: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ù),還需要對其進行分析。以結(jié)構(gòu)化形式存儲數(shù)據(jù)可簡化此任務(wù)。在本節(jié)中,我們將學(xué)習如何將從MongoDB中獲取的數(shù)據(jù)轉(zhuǎn)換為結(jié)構(gòu)化格式。6.1存儲到DataFrame中find函數(shù)從MongoDB集合返回字典,你可以將其直接插入DataFrame。首先,讓我們獲取100個MongoDB文檔,然后將這些文檔存儲到一個DataFrame中:import pandas as pd
samples=table.find().sort("_id",pymongo.DESCENDING)[:100]
df=pd.DataFrame(samples)
df.head()
該DataFrame的可讀性遠遠優(yōu)于該函數(shù)返回的默認格式。
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)通過示例討論了所有基本操作,同時我們還了解了MongoDB的幾個理論概念。在完成本文之前,讓我分享一些PyMongo的有用功能:sort:我們已經(jīng)看到了此功能的示例,此功能的目的是對文檔進行排序limit:此函數(shù)限制由find函數(shù)獲取的MongoDB文檔的數(shù)量
8. 接下來是什么?掌握了本教程中介紹的概念之后,你應(yīng)該學(xué)習與MongoDB相關(guān)的更高級的主題,如下:索引:索引是在MongoDB中對集合的某些屬性(字段)創(chuàng)建索引的過程,它使檢索過程更快。在沒有索引的集合中,當你嘗試根據(jù)字段的給定條件篩選出特定文檔時,它將掃描整個數(shù)據(jù)庫。如果有數(shù)以億計的文檔,這個過程需要時間。
索引之后,MongoDB使用大量內(nèi)存來存儲索引信息,此索引允許你根據(jù)篩選條件跳轉(zhuǎn)到特定文檔,而無需掃描整個數(shù)據(jù)庫分片:跨多臺機器存儲數(shù)據(jù)的過程稱為分片,分片有助于數(shù)據(jù)庫的水平擴展運算符:我們已經(jīng)在MongoDB中看到了$in操作符,還有一些其他有用的運算符可以執(zhí)行某些特定的功能結(jié)尾在本文中,我們學(xué)習了MongoDB的所有基本概念,這足以讓你在非結(jié)構(gòu)化數(shù)據(jù)庫的學(xué)習上有一個堅實的開端。
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-11.13立即報名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月28日立即報名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會議
-
12月19日立即報名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報名中>> OFweek2024中國智造CIO在線峰會
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍皮書》
-
精彩回顧立即查看>> 【限時免費下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
推薦專題
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市