python與MongoDB的連線

weixin_34402408發表於2017-12-13
9262853-19bcd1729c9f478b.jpg

一、配置和安裝相應的環境

主要針對python指令碼操作mongdb資料庫,所以安裝pymongo和mongodb庫。

二、建立連線到mongodb資料庫:

與PyMongo工作時,第一步是建立一個MongoClient到正在執行的mongod例項。

from pymongo import MongoClient
client = MongoClient('localhost', 27017)#比較常用

# client = MongoClient('mongodb://localhost:27017/')使用MongoDB的URI格式

建立常見的方式有兩種:一種是連線到預設的主機埠;另外一種是指定主機和固定的埠,注意一般mongodb安裝時預設的埠為:27017。

三、建立資料庫

MongoDB中的單個例項可以支援多個獨立的資料庫。當PyMongo工作訪問使用上MongoClient例項屬性的風格訪問資料庫:例如建立一個test_database資料庫。

db = client.test_database

# db = client['test-database']或者這種形式

#test_database資料庫的名稱

四、獲取集合(getting a collection)

集合是一組儲存在MongoDB中的檔案,並且可以被認為是一個表,作為大致在關聯式資料庫中的等效的。獲得在PyMongo收集工作與獲取資料庫:

collection = db.test_collection

# collection = db['test-collection']或者這種形式

有關集合(和資料庫)在MongoDB中一個重要的注意的是:當第一個檔案被插入到他們集合和資料庫時集合就被建立。

五、檔案

MongoDB中的資料是使用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()函式進行:

>>> 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的文件。

插入第一個文件後,該帖收集實際上已在伺服器上建立。我們可以通過列出所有在我們的資料庫中收集的驗證這一點:

>>> 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格式儲存資料。BSON字串都是UTF-8編碼的,所以pymongo必須確保它儲存的字串值
包含有效地UTF-8資料.常規字串(<type ‘str’>)都是有效的,可以不改變直接儲存。
Unicode字串(<type ‘unicode’>)就需要先編碼成UTF-8格式。

5.4 批量插入(Bulk Inserts)

為了讓查詢更有趣,我們多插入幾個檔案。除了單個檔案插入,也可以通過給insert_many()方法傳入一個列表(list),作為該方法的第一個引數,進行批量插入操作。這將會插入列表(list)中的每個檔案(document)到集合中去,而且只向server傳送一條命令:

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()現在返回兩個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的支援許多不同型別的高階查詢。作為一個例子,執行我們結果限制的位置早於某個日期,也由作者對結果進行排序的查詢:

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']}

六、簡單的統計

如果我們只是想知道有多少檔案匹配,我們可以執行查詢函式count()。得到所有集合中的檔案的計數:

posts.count()

結果:

3

或者那些符合特定格式的檔案:

posts.find({"author": "Mike"}).count()

結果:

2

七、刪除文件

可以使用集合的remove()方法從集合中刪除一個文件。remove方法和find、find_one一樣,也可以使用一個字典引數來指定哪個文件需要被刪除。比如,要刪除所有"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函式的建立整合案例

9262853-64efc789d2f69e76.png
9262853-5934b4b446a4b9b6.png
9262853-8a48dbd1a6cd7fde.png
9262853-7fd9b44b012279a5.png
9262853-67707316bae8b64f.png

8.2 將10條資訊寫入mongdb資料庫的案例

9262853-2a66c075309b840b.png
9262853-71173a02a391e0f1.png

相關文章