Python+Mongodb 案例解析

本教程適合于mongodb的創(chuàng)建/查詢/和基本的案例操作

注:未經(jīng)許可不得轉(zhuǎn)載

一恳谎、配置和安裝相應(yīng)的環(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)建常見的方式有兩種:一種是連接到默認(rèn)的主機(jī)端口;另外一種是指定主機(jī)和固定的端口怎诫,注意一般mongodb安裝時默認(rèn)的端口為:27017瘾晃。

三、創(chuàng)建數(shù)據(jù)庫

MongoDB中的單個實例可以支持多個獨立的數(shù)據(jù)庫幻妓。當(dāng)PyMongo工作訪問使用上MongoClient實例屬性的風(fēng)格訪問數(shù)據(jù)庫:例如創(chuàng)建一個test_database數(shù)據(jù)庫蹦误。

>>>db = client.test_database

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

>>>#test_database數(shù)據(jù)庫的名稱

四劫拢、獲取集合(getting a collection)

集合是一組存儲在MongoDB中的文件,并且可以被認(rèn)為是一個表强胰,作為大致在關(guān)系數(shù)據(jù)庫中的等效的舱沧。獲得在PyMongo收集工作與獲取數(shù)據(jù)庫:

>>>collection = db.test_collection

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

有關(guān)集合(和數(shù)據(jù)庫)在MongoDB中一個重要的注意的是:當(dāng)?shù)谝粋€文件被插入到他們集合和數(shù)據(jù)庫時集合就被創(chuàng)建。

五偶洋、文件

MongoDB中的數(shù)據(jù)是使用JSON風(fēng)格的文件代表(和存儲)熟吏。在PyMongo我們用字典來代表文件。作為一個例子玄窝,下面的字典可能被用來代表一個博客帖子牵寺,下面以一個例子來說明文件的寫入mongodb的過程:

文件的內(nèi)如如下:

>>> import datetime

>>> post = {"author": "Mike",

..."text":"My first blog post!",

..."tags":["mongodb", "python", "pymongo"],

..."date":datetime.datetime.utcnow()}

Note:請注意,文檔可以包含原生的Python類型(如datetime.datetime實例)恩脂,它會自動轉(zhuǎn)換帽氓,并從相應(yīng)的BSON類型。

5.1文件的插入

若要將文檔轉(zhuǎn)換為集合俩块,可以使用insert_one()函數(shù)進(jìn)行:

>>> posts = db.posts

>>> post_id = posts.insert_one(post).inserted_id

>>> post_id

Out[5]: ObjectId('56556b3c9d00010b2f8909cf')

當(dāng)一個文件被插入一個特殊的鍵黎休,“_id”,自動添加如果文檔沒有包含一個“_id”鍵玉凯》苡妫“_id”的值必須在這個集合是唯一的。insert_one()返回InsertOneResult的一個實例壮啊。有關(guān)“_id”的更多信息嫉鲸,請參見_id的文檔。

插入第一個文檔后歹啼,該帖收集實際上已在服務(wù)器上創(chuàng)建玄渗。我們可以通過列出所有在我們的數(shù)據(jù)庫中收集的驗證這一點:

>>> db.collection_names(include_system_collections=False)

Out[6]: [u'posts']

5.2單個文檔的獲取find_one()

查詢最基本的類型,可以在MongoDB中進(jìn)行的find_one()狸眼。該方法返回一個單一的文件匹配查詢(或無藤树,如果沒有匹配),當(dāng)你知道只有一個匹配的文件拓萌,或者只關(guān)心在第一文件匹配是非常有用的岁钓,使用find_one()來獲得職位收集的頭文件:

In [7]: posts.find_one()

Out[7]:

{u'_id': ObjectId('565583369d00010c0ad19cd6'),

u'author': u'Mike',

u'date': datetime.datetime(2015,11, 25, 9, 45, 22, 80000),

u'tags': [u'mongodb', u'python',u'pymongo'],

u'text': u'My first blog post!'}

Note:上面的結(jié)果是一個辭典匹配,先前插入的那個微王。返回文檔中包含一個“_id”屡限,這是在插入自動添加。

如果嘗試用不同的author炕倘,如“Eliot”會得到任何結(jié)果:

In [8]: posts.find_one({"author": "Eliot"})

沒有結(jié)果钧大;

如果嘗試,“Mike”會得到如下結(jié)果:

In [9]: posts.find_one({"author": "Mike"})

Out[9]:

{u'_id': ObjectId('565583369d00010c0ad19cd6'),

u'author': u'Mike',

u'date': datetime.datetime(2015,11, 25, 9, 45, 22, 80000),

u'tags': [u'mongodb', u'python',u'pymongo'],

u'text': u'My first blog post!'}

5.3通過ObjectId查詢

我們也可以找到一個位置由它的_id罩旋,這在我們的例子中是一個的ObjectId:

In [10]: post_id

Out[10]: ObjectId('565583369d00010c0ad19cd6')

In [11]: posts.find_one({"_id": post_id})

Out[11]:

{u'_id': ObjectId('565583369d00010c0ad19cd6'),

u'author': u'Mike',

u'date': datetime.datetime(2015,11, 25, 9, 45, 22, 80000),

u'tags': [u'mongodb', u'python',u'pymongo'],

u'text': u'My first blog post!'}

注意啊央,一個ObjectId存在不一樣的字符串表示:

In [13]: post_id_as_str = str(post_id)

posts.find_one({"_id":post_id_as_str}) #

沒有任何結(jié)果

在Web應(yīng)用程序中的一個常見的任務(wù)是讓從請求URL中的ObjectId眶诈,并找到匹配的文件。有必要在這種情況下將它傳遞到find_one()之前從字符串轉(zhuǎn)換的ObjectId:

from bson.objectid import ObjectId

# The web framework gets post_id from the URL and passes it as a string

def get(post_id):

# Convert from string toObjectId:

document =client.db.collection.find_one({'_id': ObjectId(post_id)})

5.4 批量插入(Bulk Inserts)

除了插入一個單一的文件瓜饥,我們也可以執(zhí)行批量插入操作逝撬,通過傳遞列表作為第一個參數(shù)insert_many()。這將插入每個文件在列表中乓土,只發(fā)送一個命令到服務(wù)器:

In [14]:

new_posts = [{"author": "Mike",

"text": "Anotherpost",

"tags":["bulk", "insert"],

"date":datetime.datetime(2009, 11, 12, 11, 14)},

{"author":"Eliot",

"title": "MongoDB isfun",

"text":"and pretty easy too!",

"date":datetime.datetime(2009, 11, 10, 10, 45)}]

result = posts.insert_many(new_posts)

result.inserted_ids

Out[14]:

[ObjectId('565589029d00010c0ad19cd7'), ObjectId('565589029d00010c0ad19cd8')]

Note:有幾個有趣的事情需要注意這個例子:

l從insert_many()宪潮,結(jié)果返回兩個的ObjectId,而且每一個都插入到了文件帐我。

lnew_posts [ 1 ]都有不同的“tags”比其他位置-沒有“標(biāo)簽”欄,我們增加了一個新的類愧膀,“title”拦键。從這可以看出MongoDB的構(gòu)架是自由化的,可以自行增加和刪減檩淋;

5.5 多文檔查詢

為了獲得更多的比一個單一的文件芬为,因為我們使用find()方法查詢的結(jié)果。find()返回游標(biāo)實例蟀悦,它允許我們遍歷所有匹配的文件媚朦。例如,我們可以遍歷的數(shù)據(jù)庫收集每一份文件:

In [16]:

for post in posts.find():

print post

{u'date': datetime.datetime(2015, 11, 25, 9, 45, 22, 80000), u'text':u'My first blog post!', u'_id': ObjectId('565583369d00010c0ad19cd6'),u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}

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

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

就像我們用find_one()一樣日戈,我們可以通過find()來限制文檔的返回結(jié)果询张。在這里,我們得到它的作者是“Mike”只有那些文件:

In [17]: for post in posts.find({"author":"Mike"}):

print post

{u'date':datetime.datetime(2015, 11, 25, 9, 45, 22, 80000), u'text': u'My first blogpost!', u'_id': ObjectId('565583369d00010c0ad19cd6'), u'author': u'Mike',u'tags': [u'mongodb', u'python', u'pymongo']}

{u'date': datetime.datetime(2009,11, 12, 11, 14), u'text': u'Another post', u'_id':ObjectId('565589029d00010c0ad19cd7'), u'author': u'Mike', u'tags': [u'bulk',u'insert']}

5.6 范圍查詢

MongoDB的支持許多不同類型的高級查詢浙炼。作為一個例子份氧,執(zhí)行我們結(jié)果限制的位置早于某個日期,也由作者對結(jié)果進(jìn)行排序的查詢:

In [20]:

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ù):

In [18]: posts.count()

Out[18]: 3

或者那些符合特定格式的文件:

In [19]: posts.find({"author": "Mike"}).count()

Out[19]: 2

七资厉、刪除文檔

可以使用集合的remove()方法從集合中刪除一個文檔厅缺。remove方法和find、find_one一樣宴偿,也可以使用一個字典參數(shù)來指定哪個文檔需要被刪除湘捎。比如,要刪除所有"author"鍵的值為"Mike"的文檔窄刘,輸入:

In [26]: posts.remove({"author": "Mike"})

Out[26]: {u'n': 4, u'ok': 1}

In [27]: 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ù)庫的案例

源碼見附錄

注:未經(jīng)許可不得轉(zhuǎn)載都哭!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秩伞,一起剝皮案震驚了整個濱河市逞带,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纱新,老刑警劉巖展氓,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脸爱,居然都是意外死亡遇汞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門簿废,熙熙樓的掌柜王于貴愁眉苦臉地迎上來空入,“玉大人,你說我怎么就攤上這事族檬⊥嵊” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵单料,是天一觀的道長埋凯。 經(jīng)常有香客問我,道長扫尖,這世上最難降的妖魔是什么白对? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮换怖,結(jié)果婚禮上甩恼,老公的妹妹穿的比我還像新娘。我一直安慰自己沉颂,他們只是感情好媳拴,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兆览,像睡著了一般屈溉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抬探,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天子巾,我揣著相機(jī)與錄音,去河邊找鬼小压。 笑死线梗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怠益。 我是一名探鬼主播仪搔,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜻牢!你這毒婦竟也來了烤咧?” 一聲冷哼從身側(cè)響起偏陪,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煮嫌,沒想到半個月后笛谦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡昌阿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年饥脑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懦冰。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡灶轰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刷钢,到底是詐尸還是另有隱情笋颤,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布闯捎,位于F島的核電站椰弊,受9級特大地震影響许溅,放射性物質(zhì)發(fā)生泄漏瓤鼻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一贤重、第九天 我趴在偏房一處隱蔽的房頂上張望茬祷。 院中可真熱鬧,春花似錦并蝗、人聲如沸祭犯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沃粗。三九已至,卻和暖如春键畴,著一層夾襖步出監(jiān)牢的瞬間最盅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工起惕, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留涡贱,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓惹想,卻偏偏與公主長得像问词,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嘀粱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容