最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(MongoDB 篇)

image

1. 前言

前面 4 篇文章,分別對 Python 處理 Mysql、Sqlite匠题、Redis啊央、Memcache 數(shù)據(jù)進(jìn)行了總結(jié)眶诈,本篇文章繼續(xù)聊另外一種數(shù)據(jù)類型:MongoDB

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Mysql 篇)

?最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Sqlite 篇)

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Redis 篇)

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Memcached 篇)

MongoDB 是基于分布式存儲,由 C++ 編寫的開源的 NoSql 數(shù)據(jù)庫

MongoDB 的內(nèi)容存儲類似 JSON 對象瓜饥,數(shù)據(jù)結(jié)構(gòu)包含 3 種

分別是:

  • 數(shù)據(jù)庫 - Databases

    對應(yīng)關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)庫(Database)

  • 集合 - Collection

    對應(yīng)關(guān)系型數(shù)據(jù)庫中的 Table 表(Table)

  • 文檔 - Document

    對應(yīng)數(shù)據(jù)庫表中的一條數(shù)據(jù)(Row Data)

2. 準(zhǔn)備

Python 操作 MongoDB逝撬,常見的兩種方式是:Pymongo、Mongoengine

其中

  • Mongoengine:面相對象乓土,針對文檔型數(shù)據(jù)庫的 ORM宪潮,直接繼承于 Document 文檔,對文檔進(jìn)行增刪改查

  • Pymongo:通過 JSON 和 MongoDB 進(jìn)行通信趣苏,將 MongoDB 的數(shù)據(jù)映射成 Python 內(nèi)置的數(shù)據(jù)類型

首先狡相,我們通過 pip3 命令安裝依賴

# 安裝依賴
# pymongo
pip3 install pymongo

# mongoengine
pip3 install mongoengine

下面分別對 Pymongo 和 Mongoengine 進(jìn)行說明

3. PyMongo

首先,創(chuàng)建一個數(shù)據(jù)庫連接對象

創(chuàng)建數(shù)據(jù)庫連接對象有二種方式食磕,分別是:多參數(shù)尽棕、字符串拼接

import pymongo

# 創(chuàng)建數(shù)據(jù)庫連接對象的兩種方式
# 方式一:多參數(shù)
self.client = pymongo.MongoClient(host='ip地址', port=27017, username="root", password="123456",
                                          authMechanism="SCRAM-SHA-1")
# 方式二:拼接
# self.client = pymongo.MongoClient('mongodb://root:123456@ip地址:27017/')

接著,通過數(shù)據(jù)庫連接對象指定要操作的數(shù)據(jù)庫和操作集合

比如:要操作數(shù)據(jù)庫 temp 中的 students 集合

# 指定要操作的數(shù)據(jù)庫:temp
self.db = self.client.temp

# 指定要操作集合students
self.collection_students = self.db.students

接著彬伦,我們來實現(xiàn)增刪改查操作

1滔悉、新增

新增包含:新增單條數(shù)據(jù)和多條數(shù)據(jù)

單條數(shù)據(jù)插入對應(yīng)的方法是:

insert_one(dict)

該方法的返回值類型為 InsertOneResult

通過 inserted_id 屬性伊诵,可以獲取插入數(shù)據(jù)的 _id 值

temp_data = {
    "id": "1",
    "name": "xag",
    "age": 18
}

# 1、直接調(diào)用集合的insert_one()方法插入數(shù)據(jù)(插入一條數(shù)據(jù))
result = self.collection_students.insert_one(temp_data)

# 返回值為InsertOneResult回官,通過inserted_id屬性獲取_id的值
print(result.inserted_id)

多條數(shù)據(jù)插入對應(yīng)的方法是:

insert_many([dict1,dict2...])

該方法的返回值類型為 InsertManyResult

通過 inserted_ids 屬性曹宴,可以獲取插入數(shù)據(jù)的 _id 屬性值列表

# 2、插入多條數(shù)據(jù)-insert_many()
result = self.collection_students.insert_many([temp_data, temp_data2])

# 返回值為InsertManyResult孙乖,通過inserted_ids屬性獲取插入數(shù)據(jù)的_id列表值
print(result.inserted_ids)

2浙炼、查詢

使用 PyMongo 查詢 MongoDB 數(shù)據(jù)庫,常用方法如下:

  • 通過某一個屬性鍵值對唯袄,去查詢一條記錄 - find_one()

  • 通過 ObjectId 值去查詢某一條記錄 - find_one()

  • 通過某一個屬性鍵值對弯屈,去查詢多條記錄 - find()

  • 通過大于、小于恋拷、等于等條件去比較查詢

  • 正則匹配查詢

前面 3 種查詢方式资厉,由于比較簡單,直接給出實例:

def manage_query(self):
    """查詢數(shù)據(jù)"""
    # 1蔬顾、通過某個屬性鍵值對宴偿,去查詢一條記錄 find_one()
    # 返回值為字典類型
    # {'_id': ObjectId('5f5c437cfe49fa9a16664179'), 'id': '1', 'name': 'xag', 'age': 18}
    result = self.collection_students.find_one({"name": "xag"})
    print(result)

    # 2、通過ObjectId值去查詢某一條記錄
    result = self.collection_students.find_one({"_id": ObjectId('5f5c437cfe49fa9a16664179')})
    print(result)

    # 3.1 查詢多條記錄 find()
    # 返回值為一個游標(biāo)(生成器)诀豁,pymongo.cursor.Cursor
    result_lists = self.collection_students.find({"name":"xag"})
    print(result_lists)
    for item in result_lists:
        print(item)

條件比較查詢窄刘,包含:大于(

gt)、大于等于(
gte)舷胜、小于(
lt)娩践、小于等于(
lte)、不等于(
ne)烹骨、在范圍內(nèi)(
in)翻伺、不在范圍內(nèi)($nin)

比如:查詢年齡大于 18 歲的數(shù)據(jù)

# 3.2 條件比較查詢,包含大于($gt)沮焕、大于等于($gte)吨岭、小于($lt)、小于等于($lte)峦树、不等于($ne)辣辫、在范圍內(nèi)($in)、不在范圍內(nèi)($nin)
# 查詢年齡大于18歲的記錄
result = self.collection_students.find({'age': {'$gt': 18}})
for item in result:
    print(item)

正則匹配查詢魁巩,包含:

  • $regex:匹配正則表達(dá)式

  • $exists:屬性是否存在

  • $type:數(shù)據(jù)類型判斷

  • $mod:數(shù)據(jù)模操作

  • $text:文本包含查詢

  • $where:高級條件查詢

比如急灭,查詢 name 值以 "xag" 開頭的數(shù)據(jù)

# 正則匹配查詢
results = self.collection_students.find({'name': {'$regex': '^xag.*'}})
for item in results:
    print(item)

關(guān)于查詢更加復(fù)雜的功能可以參考:

https://docs.mongodb.com/manual/reference/operator/query/

3、更新

更新操作包含:更新一條記錄和更新多條記錄

其中,更新一條記錄對應(yīng)的方法是:

update_one(query,update_content)

參數(shù)包含:查詢的條件、要修改的內(nèi)容

# 1本橙、修改一條記錄 update_one(query,update_data)
# 方法中有兩個參數(shù),分別是:查詢條件点楼、要修改的內(nèi)容
# 查詢條件
query_condition = {"name": "xag"}
# 要修改的內(nèi)容
update_content = {"$set": {"name": "星安果"}}
# 使用update_one() 方法進(jìn)行更新一條記錄
result = self.collection_students.update_one(query_condition, update_content)

通過返回的結(jié)果可以獲取查詢匹配的記錄個數(shù)及影響的記錄個數(shù)

# matched_count:匹配的記錄個數(shù)
# modified_count:影響的記錄個數(shù)
print(result.matched_count, result.modified_count)

更新多條記錄對應(yīng)的方法是:

update_many(query,update_content)

方法中的參數(shù)、返回值與修改單條記錄類似

# 2白对、修改多條記錄 update_many(query,update_data)
# 查詢條件
query_condition = {"name": {"$regex": "^星.*"}}
# 要修改的內(nèi)容
update_content = {"$set": {"name": "xag"}}
# 將文檔中name以星開頭的記錄都設(shè)置為xag
result = self.collection_students.update_many(query_condition, update_content)
print(result)
print(result.matched_count, result.modified_count)

4掠廓、刪除

刪除同樣包含:刪除查詢到的第一條記錄、刪除查詢到的所有記錄

分別對應(yīng)的方法是:delete_one(query)甩恼、delete_many(query)

另外蟀瞧,在返回結(jié)果中可以獲取到真實被刪除的數(shù)目

def manage_remove(self):
    """
    刪除操作
    :return:
    """
    # 1、刪除查詢到的第一條記錄 delete_one()
    # result = self.collection_students.delete_one({'name': "xag2"})
    # print(result)
    # 刪除的數(shù)目
    # print(result.deleted_count)

    # 2条摸、刪除多條記錄 delete_many()
    result = self.collection_students.delete_many({'name': "xag"})
    print(result)
    # 刪除的數(shù)目
    print(result.deleted_count)

5悦污、計數(shù)和排名

常用的方法包含:

  • limit(num):限制返回的結(jié)果數(shù)量

  • skip(num):忽略 num 個元素,從 num + 1 個元素開始查看

  • count_documents():查看集合中所有的文檔數(shù)量钉蒲,也可以根據(jù)條件去查詢滿足的文檔數(shù)量

  • sort():升序或者降序

def manage_count_and_sort(self):
    """
    計數(shù)和排序
    :return:
    """
    # 1切端、限制返回的結(jié)果數(shù)量 - limit()
    # result = self.collection_students.find().limit(2)
    # for item in result:
    #     print(item)

    # 2、偏移  skip()
    # 比如:忽略前面兩個元素顷啼,從第3個元素開始查看
    # result = self.collection_students.find().skip(2)
    # print([result['name'] for result in result])

    # 3.1 查詢出集合中所有的文檔數(shù)量 count_documents()
    # result = self.collection_students.count_documents({})
    # print(result)

    # 3.2 根據(jù)條件去查詢踏枣,然后判斷結(jié)果數(shù)目
    # query_regex = {'name': {'$regex': '^xag.*'}}
    # result = self.collection_students.count_documents(query_regex)
    # print(result)

    # 4、排序 sort()
    # pymongo.ASCENDING:升序钙蒙,DESCENDING:降序
    result = self.collection_students.find().sort('name', pymongo.DESCENDING)
    print([result['name'] for result in result])

4. Mongoengine

在使用 Mongoengine 操作 MongoDB 之前茵瀑,需要先定義一個 Document 的子類

該子類對應(yīng) MongoDB 中的文檔,內(nèi)部加入的靜態(tài)變量(包含:類型躬厌、長度等)對應(yīng)數(shù)據(jù)庫文檔中的數(shù)據(jù)

from mongoengine import *

# Document的子類马昨,對應(yīng)文檔對象
class Student(Document):
    name = StringField(required=True, max_length=500)
    age = IntField(required=True, default=18)
    create_time = DateTimeField(default=datetime.now)

    # 配置元數(shù)據(jù)
    # 指定集合為student
    meta = {'collection': 'student', 'strict': False}

利用 Mongoengine 內(nèi)置的 connect() 方法,連接指定的數(shù)據(jù)庫

# 連接數(shù)據(jù)庫temp
def __init__(self):
    # 連接數(shù)據(jù)庫
?    # 數(shù)據(jù)庫名稱:temp
    # auth方式:SCRAM-SHA-1
    result = connect('temp', host='ip地址', port=27017,
                     username='root', password='123456', authentication_source='admin',
                     auth

接著烤咧,我們來實現(xiàn)增刪改查操作

1偏陪、新增

使用 Mongoengine 新增一條記錄到數(shù)據(jù)庫非常方便

只需要實例化一個文檔對象,調(diào)用 save() 方法煮嫌,即可以存儲一條記錄到數(shù)據(jù)庫當(dāng)中

def insert(self):
    """
    插入數(shù)據(jù)
    :return:
    """
    person = Student(name='xag2', age=20)
    person.save()

2笛谦、查詢

常見的查詢操作包含:

  • 查詢集合中的所有記錄

  • 查詢第一條記錄

  • 通過主鍵 _ID,來查詢數(shù)據(jù)

  • 條件查詢

對應(yīng)的代碼如下:

def query(self):
    """
    普通查詢
    :return:
    """
    # 1昌阿、查看集合中所有數(shù)據(jù)
    # students = Student.objects.all()
    # print([item['name'] for item in students])

    # 2饥脑、查詢第一條記錄
    # student = Student.objects.first()
    # print(student.name, student.age, student.create_time)

    # 3、通過主鍵_ID來查詢數(shù)據(jù)
    result = Student.objects.filter(pk="5f5c5b34f5b0c049707a1710").first()
    print(result.name, result.age, result.create_time)

    # 4懦冰、條件查詢
    # 查詢年齡在18-20歲的數(shù)據(jù)
    # __gte:大于等于灶轰;__lte:小于等于
    # 默認(rèn)是升序,可以加一個:-刷钢,代表逆序
    # students = Student.objects(age__gte=18, age__lte=20).order_by('name')
    students = Student.objects(age__gte=18, age__lte=20).order_by('-name')
    # for item in students:
    #     print(item.name, item.age, item.create_time)

值得一提的是笋颤,Mongoengine 提供了關(guān)鍵字 Q 來實現(xiàn)高級查詢

比如:查詢 name 字段值為 xag,年齡為 18 歲的數(shù)據(jù)

def query_advance(self):
    """
    高級查詢
?    :return:
    """
    # 查看name為xag,age為18的記錄的第一條
    student = Student.objects(Q(name="xag") & Q(age=18)).first()
    print(student.name, student.age, student.create_time)

進(jìn)階操作可以參考:

https://docs.mongoengine.org/guide/querying.html

3伴澄、更新

Mongoengine 提供了 filter() 和 update() 兩個方法赋除,分別用于過濾待更新的數(shù)據(jù),指定的更新內(nèi)容

def update(self):
    """
    更新記錄
    :return:
    """
    # 1非凌、修改所有記錄
    # 修改name為xag的年齡都減少1歲
    # 增加一歲:inc__age=1
    # 減少一歲:dec__age=1
    # Student.objects.filter(name="xag").update(dec__age=1)
    # Student.objects.filter(name="xag").update(inc__age=1)

    # name為xag举农,age小于18的的所有記錄,更新為age=23
    # __lt:小于
    # __lte:小于等于
    # __gt:大于
    # __gte:大于等于
    # Student.objects.filter(name="xag", age__lt=18).update(age=23)
    # Student.objects.filter(age__lte=20).update(age=23)

如果只需要更改查詢到的第一條記錄敞嗡,可以使用 update_one() 方法

# 2颁糟、修改一條記錄
# 年齡減少5歲
Student.objects.filter(name='xag').update_one(dec__age=5)

4、刪除

刪除操作對應(yīng) delete() 方法

同樣喉悴,可以利用 filter() 和 first() 方法限制要刪除的范圍

def delete(self):
    """
    刪除數(shù)據(jù)
    :return:
    """
    # 1棱貌、刪除查詢到的第一條記錄
    # Student.objects.filter(name="xag").first().delete()

    # 2、刪除多條記錄
    # Student.objects.filter(name="xag").delete()

    # 刪除name值以xag開頭的所有記錄
    Student.objects.filter(name__startswith="xag").delete()

5.最后

本篇文章講解了 Python 操作 MongoDB粥惧,最常用的兩種使用方式

我已經(jīng)將文中全部源碼上傳到后臺键畴,關(guān)注公眾號「 AirPython 」后回復(fù)「 dball 」即可獲得全部源碼

如果你覺得文章還不錯,請大家 點贊突雪、分享起惕、留言下,因為這將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動力咏删!

推薦閱讀

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Mysql篇)

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Sqlite篇)

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Redis篇)

最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(Memc篇)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惹想,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子督函,更是在濱河造成了極大的恐慌嘀粱,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辰狡,死亡現(xiàn)場離奇詭異锋叨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宛篇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門娃磺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叫倍,你說我怎么就攤上這事偷卧。” “怎么了吆倦?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵听诸,是天一觀的道長。 經(jīng)常有香客問我蚕泽,道長晌梨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮仔蝌,結(jié)果婚禮上砸逊,老公的妹妹穿的比我還像新娘。我一直安慰自己掌逛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布司倚。 她就那樣靜靜地躺著豆混,像睡著了一般。 火紅的嫁衣襯著肌膚如雪动知。 梳的紋絲不亂的頭發(fā)上皿伺,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機(jī)與錄音盒粮,去河邊找鬼鸵鸥。 笑死,一個胖子當(dāng)著我的面吹牛丹皱,可吹牛的內(nèi)容都是我干的妒穴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼摊崭,長吁一口氣:“原來是場噩夢啊……” “哼讼油!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呢簸,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤矮台,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后根时,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘦赫,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年蛤迎,在試婚紗的時候發(fā)現(xiàn)自己被綠了确虱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忘苛,死狀恐怖蝉娜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扎唾,我是刑警寧澤召川,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站胸遇,受9級特大地震影響荧呐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一倍阐、第九天 我趴在偏房一處隱蔽的房頂上張望概疆。 院中可真熱鬧,春花似錦峰搪、人聲如沸岔冀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽使套。三九已至,卻和暖如春鞠柄,著一層夾襖步出監(jiān)牢的瞬間侦高,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工厌杜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留奉呛,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓夯尽,卻偏偏與公主長得像瞧壮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匙握,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354