一、配置和安裝相應的環(huán)境
主要針對python腳本操作mongdb數(shù)據(jù)庫忆蚀,所以安裝pymongo和mongodb庫秃踩。
二、創(chuàng)建連接到mongodb數(shù)據(jù)庫:
與PyMongo工作時宙橱,第一步是建立一個MongoClient到正在運行的mongod實例。
from pymongo import MongoClient
client = MongoClient('localhost', 27017)#比較常用
# client = MongoClient('mongodb://localhost:27017/')使用MongoDB的URI格式
創(chuàng)建常見的方式有兩種:一種是連接到默認的主機端口蘸拔;另外一種是指定主機和固定的端口师郑,注意一般mongodb安裝時默認的端口為:27017。
三调窍、創(chuàng)建數(shù)據(jù)庫
MongoDB中的單個實例可以支持多個獨立的數(shù)據(jù)庫宝冕。當PyMongo工作訪問使用上MongoClient實例屬性的風格訪問數(shù)據(jù)庫:例如創(chuàng)建一個test_database數(shù)據(jù)庫。
db = client.test_database
# db = client['test-database']或者這種形式
#test_database數(shù)據(jù)庫的名稱
四邓萨、獲取集合(getting a collection)
集合是一組存儲在MongoDB中的文件地梨,并且可以被認為是一個表,作為大致在關系數(shù)據(jù)庫中的等效的缔恳。獲得在PyMongo收集工作與獲取數(shù)據(jù)庫:
collection = db.test_collection
# collection = db['test-collection']或者這種形式
有關集合(和數(shù)據(jù)庫)在MongoDB中一個重要的注意的是:當?shù)谝粋€文件被插入到他們集合和數(shù)據(jù)庫時集合就被創(chuàng)建宝剖。
五、文件
MongoDB中的數(shù)據(jù)是使用JSON風格的文件代表(和存儲)歉甚。在PyMongo我們用字典來代表文件诈闺。作為一個例子,下面的字典可能被用來代表一個博客帖子铃芦,下面以一個例子來說明文件的寫入mongodb的過程:
文件的內如如下:
import datetime
post = {"author": "Mike",
..."text":"My first blog post!",
..."tags":["mongodb", "python", "pymongo"],
..."date":datetime.datetime.utcnow()}
Note:請注意雅镊,文檔可以包含原生的Python類型(如datetime.datetime實例),這些類型的值會被自動在原生類型和BSON格式之間轉換刃滓。
5.1文件的插入
若要將文檔轉換為集合仁烹,可以使用insert_one()函數(shù)進行:
>>> posts = db.posts
>>> post_id = posts.insert_one(post).inserted_id
>>> post_id
Out[5]: ObjectId('56556b3c9d00010b2f8909cf')
當一個文件被插入一個特殊的鍵,“_id”咧虎,自動添加如果文檔沒有包含一個“_id”鍵卓缰。“_id”的值必須在這個集合是唯一的砰诵。insert_one()返回InsertOneResult的一個實例征唬。有關“_id”的更多信息,請參見_id的文檔茁彭。
插入第一個文檔后总寒,該帖收集實際上已在服務器上創(chuàng)建。我們可以通過列出所有在我們的數(shù)據(jù)庫中收集的驗證這一點:
>>> db.collection_names(include_system_collections=False)
Out[6]: [u'posts']
5.2單個文檔的獲取find_one()
在MongoDB中理肺,最基本的查詢是find_one摄闸。這個方法返回一個符合查詢的文件,或者在沒有匹配的時候返回None妹萨。
當只有一個文件符合條件的時候年枕,或者只對第一個符合條件的文件感興趣的時候,這個方法是很有用的乎完。
我們用find_one()來獲取posts collection 里的第一個文件:
>>> posts.find_one()
{'date': datetime.datetime(2016, 9, 27, 3, 56, 26, 78000), 'author': 'Mike',
'_id': ObjectId('57e9edea77eddf223cde3314'), 'tags': ['mongodb', 'python', 'pymongo'],
'text': 'My first blog post!'}
返回結果是一個我們之前插入的符合條件的字典類型值熏兄。
注意,返回的文件里包含_id這個鍵值树姨,這是自動添加的摩桶。
find_one()還支持對特定元素進行匹配的查詢。限制我們文檔的作者是"Mike",可以這么做:
>>> posts.find_one({"author":"Mike"})
{'date': datetime.datetime(2016, 9, 27, 3, 56, 26, 78000), 'author': 'Mike',
'_id': ObjectId('57e9edea77eddf223cde3314'), 'tags': ['mongodb', 'python', 'pymongo'],
'text': 'My first blog post!'}
如果我們用不同的作者娃弓,比如:"Eliot",將不會得到結果典格。
>>> posts.find_one({"author":"Eliot"})
>>>
5.3 通過ObjectId查詢
通過_id也可以進行查詢,在例子中就是ObjectId:
>>> post_id
ObjectId('57eb54a877eddf292cbea0a8')
>>> posts.find_one({"_id": post_id})
{'date': datetime.datetime(2016, 9, 28, 5, 25, 53, 6000), 'author': 'Mike',
'_id': ObjectId('57eb54a877eddf292cbea0a8'), 'tags': ['mongodb', 'python'],
'text': 'My first blog post!'}
注意:ObjectId 并不等同于它的字符串形式台丛。
>>> post_id_as_str = str(post_id)
>>> posts.find_one({"_id": post_id_as_str}) #No result
>>>
在web應用的一個常見任務就是在request的URL里獲取ObjectId耍缴,然后找到與之匹配的文件。
在本例中挽霉,必須要先從字符串轉換為ObjectId防嗡,然后傳給find_one:
>>> from bson.objectid import ObjectId
#從URL里獲取post_id,然后把它作為字符串傳入
>>> def get(post_id):
#將字符串轉換為ObjectId
document = client.db.collection.find_one({"_id": ObjectId(post_id)})
小插曲:
MongoDB以BSON格式保存數(shù)據(jù)侠坎。BSON字符串都是UTF-8編碼的蚁趁,所以pymongo必須確保它保存的字符串值
包含有效地UTF-8數(shù)據(jù).常規(guī)字符串(<type ‘str’>)都是有效的,可以不改變直接保存实胸。
Unicode字符串(<type ‘unicode’>)就需要先編碼成UTF-8格式他嫡。
5.4 批量插入(Bulk Inserts)
為了讓查詢更有趣番官,我們多插入幾個文件。除了單個文件插入钢属,也可以通過給insert_many()方法傳入一個列表(list)徘熔,作為該方法的第一個參數(shù),進行批量插入操作。這將會插入列表(list)中的每個文件(document)到集合中去淆党,而且只向server發(fā)送一條命令:
new_posts = [{"author": "Mike","text": "Another post!","tags": ["bulk", "insert"],"date": datetime.datetime(2009, 11, 12, 11, 14)},{"author": "Eliot","title": "MongoDB is fun","text": "and pretty easy too!","date": datetime.datetime(2009, 11, 10, 10, 45)}]
>>> result = posts.insert_many(new_posts)
>>> result.inserted_ids
[ObjectId('57eb700b77eddf292cbea0a9'), ObjectId('57eb700b77eddf292cbea0aa')]
這個例子里有一些比較有趣的地方:
insert_many()現(xiàn)在返回兩個ObjectId實例酷师,每個代表一個插入的文件。
new_posts[1]與其他的posts內容格式不相同,里面沒有"tags”染乌。另外我們增加了一個新的“title”域山孔。這就是MongoDB所提到的無schema特點。
5.5 多文檔查詢
為了得到更多的文件荷憋,我們使用find()方法台颠。find()返回一個Cursor實例,可使我們遍歷所有匹配的文件。
比如遍歷每個posts collection里的文件:
>>> for post in posts.find():
post
與使用find_one()時候相同台谊,可以傳入一個文件來限制查詢結果蓉媳。比如查詢作者"Mike" 文件:
>>> for post in posts.find({"author":"Mike"}):
post
5.6 范圍查詢
MongoDB的支持許多不同類型的高級查詢。作為一個例子锅铅,執(zhí)行我們結果限制的位置早于某個日期酪呻,也由作者對結果進行排序的查詢:
d = datetime.datetime(2009, 11, 12, 12)
for post in posts.find({"date": {"$lt":d}}).sort("author"):
print post
結果:
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'andpretty easy too!', u'_id': ObjectId('565589029d00010c0ad19cd8'), u'author':u'Eliot', u'title': u'MongoDB is fun'}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Anotherpost', u'_id': ObjectId('565589029d00010c0ad19cd7'), u'author': u'Mike',u'tags': [u'bulk', u'insert']}
六、簡單的統(tǒng)計
如果我們只是想知道有多少文件匹配盐须,我們可以執(zhí)行查詢函數(shù)count()玩荠。得到所有集合中的文件的計數(shù):
posts.count()
結果:
3
或者那些符合特定格式的文件:
posts.find({"author": "Mike"}).count()
結果:
2
七、刪除文檔
可以使用集合的remove()方法從集合中刪除一個文檔贼邓。remove方法和find阶冈、find_one一樣,也可以使用一個字典參數(shù)來指定哪個文檔需要被刪除塑径。比如女坑,要刪除所有"author"鍵的值為"Mike"的文檔,輸入:
>>>posts.remove({"author": "Mike"})
{u'n': 4, u'ok': 1}
>>>for nl in posts.find():
print nl
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'andpretty easy too!', u'_id': ObjectId('565589029d00010c0ad19cd8'), u'author':u'Eliot', u'title': u'MongoDB is fun'}
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'andpretty easy too!', u'_id': ObjectId('56559fb89d00010d55ba1d12'), u'author':u'Eliot', u'title': u'MongoDB is fun'}
八、案例解析
8.1 常見mongoDB函數(shù)的創(chuàng)建集成案例
8.2 將10條信息寫入mongdb數(shù)據(jù)庫的案例