python 操作mongodb


以前搞過python和mongodb,時間長了 就忘了, 並且每次找百度也不是特別方便, 今天就此整理一下。首先來看最基礎的

CRUD操作

from pymongo import MongoClient 
 
#創建連接
conn =  MongoClient("mongodb://root:root@127.0.0.1:27017/")
 
#創建數據庫對象
db = conn.stu 
 
#創建集合對象
myset = db.class4 
 
print(dir(myset))
 
# 插入操作
myset.insert({'name':'張鐵林','King':'乾隆'})
myset.insert([{'name':'張國立','King':'康熙'}, {'name':'陳道明','King':'康熙'}])
myset.insert_many([{'name':'唐國強','King':'雍正'}, {'name':'陳建斌','King':'雍正'}])
myset.insert_one({'name':'鄭少秋','King':'乾隆'})
myset.save({'_id':1,'name':'聶遠','King':'乾隆'}) 
 
# 查找操作
 
cursor = myset.find({},{'_id':0})
 
# i為每個文檔對應的字典
for i in cursor:
    print(i['name'],'--->',i['King'])
 
myset = db.class1 
# 操作符使用引號變為字符串
cursor = myset.find({'age':{'$gt':30}},{'_id':0})
 
cursor.limit(2)#獲取前兩個文檔
cursor.skip(2) #跳過前兩個
cursor.sort([('age',-1),('name',1)]) #對游標內容排序
 
for i in cursor:
    print(i)
#print(cursor.next()) #獲取下一個文檔
 
 
dic = {'$or':[{'age':{'$gt':35}},{'gender':'w'}]}
data = myset.find_one(dic,{'_id':0})
print(data)
 
# 修改操作
myset.update({'name':'張國立'},{'$set':{'king_name':'玄燁'}})
myset.update({'name':'霍建華'},{'$set':{'King':'乾隆'}}, upsert = True)
myset.update({'King':'乾隆'},{'$set':{'king_name':'弘歷'}},multi = True)
myset.update_one({'King':'康熙'},{'$set':{'king_name':'愛新覺羅玄燁'}})
myset.update_many({'King':'雍正'}, {'$set':{'king_name':'胤禛'}})
 
# 刪除操作
myset.remove({'King':'康熙'})
myset.remove({'King':'乾隆'},multi = False)
 
#查找並刪除
print(myset.find_one_and_delete({'King':'乾隆'}))
 
#關閉連接
conn.close()

索引操作

from pymongo import MongoClient 
 
#創建連接
conn = MongoClient("mongodb://root:root@127.0.0.1:27017/")
 
#創建數據庫對象
db = conn['stu'] 
 
myset = db['class1'] 
 
# 刪除所有索引
myset.drop_indexes()
 
# 創建索引
index = myset.ensure_index('name')
# 創建復合索引
index = myset.ensure_index([('name',-1),('age',1)])
print(index)
 
# 刪除一個索引
myset.drop_index('name_1')
 
# 創建特殊索引
index = myset.ensure_index('name',name = "myIndex", unique = True,sparse = True)
 
# 查看集合中的索引
for i in myset.list_indexes():
    print(i)
 
myset = db.class4 
 
l = [
    {'$group':{'_id':'$King','num':{'$sum':1}}},
    {'$match':{'num':{'$gt':1}}}
]
 
cursor = myset.aggregate(l)
for i in cursor:
    print(i)
 
conn.close()

以二進制的形式 讀寫文件(以圖片為例)

from pymongo import MongoClient 
import bson.binary 
 
conn = MongoClient("mongodb://root:root@127.0.0.1:27017/")
db = conn.images 
myset = db.img 
 
#存儲
f = open('/root/test.jpg','rb')
 
#轉換為mongodb的二進制數據存儲形式
content = bson.binary.Binary(f.read())
 
#插入到數據庫
myset.insert({'filename':'test.jpg','data':content})
 
#提取
 
data = myset.find_one({'filename':'test.jpg'})
 
#通過字典獲取到數據庫內容寫入本地
with open('/root/test2.jpg','wb') as f:
    f.write(data['data'])
 
conn.close()

借用GridFS來處理文件

from pymongo import MongoClient
from gridfs import *
 
conn = MongoClient("mongodb://root:root@127.0.0.1:27017/")
db = conn.image 
 
#存儲
f = open('/root/test.jpg','rb')
#創建寫入流
imgput = GridFS(db)
#將數據寫入,文件類型和名稱通過前面的分割得到
insertimg=imgput.put(f,content_type='jpg',filename='/root/test.jpg')
f.close()
#創建成功后,會在集合中生成fs.flies和fs.chunks
 
gridFS = GridFS(db, collection="fs")
for grid_out in gridFS.find():
    data = grid_out.read() # 獲取圖片數據
    outf = open('/root/test3.jpg','wb')#創建文件
    outf.write(data)  # 存儲圖片
    outf.close()
 
conn.close()

有關GridFS的描述:

一、概述

    GridFS是基於mongodb存儲引擎是實現的“分布式文件系統”,底層基於mongodb存儲機制,和其他本地文件系統相比,它具備大數據存儲的多個優點。GridFS適合存儲超過16MB的大型文件,不過16M數據在當今互聯網時代,已經不足為奇。我們可以使用GridFS構建大規模的“圖片服務器”、“文檔服務器”、“視頻、音頻”文件服務器,GridFS對於web應用,可以結合nginx插件“ningx-gridfs”能夠簡單的實現負載均衡等特性,非常便捷;可以簡單認為GridFS是為web應用而生。個人認為,目前架構比較簡單的NoSQL文件系統中GridFS是最優秀的。

    GridFS並不是將單個文件直接存儲為一個document,而是將文件分成多個parts或者說chunks,然后將每個chunk作為作為一個單獨的document存儲,然后將chunks有序保存。默認情況下,GridFS的chunk大小位255k。GridFS使用2個collections來存儲這些文件,一個collection存儲文件的chunks(實際文件數據),另一個則存儲文件的metadata(用戶自定義的屬性,filename,content-type等)。

    當用戶查詢GridFS中的文件時,客戶端或者driver將會重新按序組裝這些chunks。用戶可以range查詢文件,也可以獲取文件的任意部分的信息,比如:跳過(skip)視頻或者音頻(任何文件)的中間部,實現“range access of single file”。

    對於mongodb而言,每個document最大尺寸為16M,如果想存儲一條數據(比如一個文件)超過16M,那么只能使用GridFS支持;GridFS可以支持單個文件尺寸達到數G,讀取文件時可以分段讀取。此外,GridFS可以從Mongodb的高性能、高可用特性中獲益,比如我們可以在“replica set”或者“sharding”架構模式下使用GridFS。

二、使用場景

    document的大小超過16M是使用GridFS的條件之一,因為mongodb普通的collection無法支持16M以上的document,我們不得不選擇其他方案;在一些情況下,將這些大文件存儲在GridFS中,比直接存儲在本地文件系統中更加適合:

    1)如果你的文件系統對每個目錄下文件的個數有限制(或者太多,將會影響文件的打開速度等)。

    2)如果你的文件數據,有分數據中心鏡像保存(大數據情況,可用性保證)。

    3)如果你希望訪問一個超大的文件,而不希望將它全部加入內存,而是有“range access”的情況,即分段讀取,那么GridFS天生就具備這種能力,你可以隨意訪問任意片段。

    對於一個大文件,如果你希望原子性的更新它的全部內容,那么GridFS將不適合;比如同時更新一個文件的多個chunk,因為mongodb本身沒有事務機制。

    對於小於16M的文件,比如一些圖片、CSS、js文件等,應該將它們直接存儲在普通的collection中而非GridFS(bindata,參見org.bson.types.Binary),因為它們通常較小,GridFS無法發揮其優勢。當然,你為了統一application的“文件系統”存儲方式,也可以將這些小文件保存在GridFS中,性能也不會差的太多,為了提升性能,對這些小文件,可以在存儲時手動設置它的chunkSize,避免文件被切分成多個chunks來提高性能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM