Pymongo Tutorial & Pymongo入門教
教程
這教程是pymongo和Mongo的一個簡單介紹。看完後應該對Pymongo對Mongo的基本操作認識了。
前置條件
開始之前,安裝PyMongo和Mongo。確保在python互動介面執行import不報錯:
1
|
>>> import
pymongo |
你需要有一個已經在執行的MongoDB例項。如果你已經下載安裝了,可以這樣啟動:
1
|
$
mongod |
通過MongoClient建立一個連線。
開始使用PyMongo的第一步是建立一個MongoClient
,對應於MongoDB例項。操作起來so easy:
1
2
|
>>>
from pymongo import
MongoClient >>>
client = MongoClient() |
上面程式碼將會連線預設的host和port。當然也可指定:
1
|
>>>
client = MongoClient( 'localhost' , 27017 ) |
或者用 MongoDB URI 格式:
1
|
>>>
client = MongoClient( 'mongodb://localhost:27017/' ) |
獲取一個資料庫
一個MongoDB例項可以支援多個獨立的資料庫。使用PyMongo時,可以通過訪問MongoClient
的屬性的方式來訪問資料庫:
1
|
>>>
db = client.test_database |
如果資料庫名字使屬性訪問方式不能用(類似test-database),也可以通過訪問字典值的方式:
1
|
>>>
db = client[ 'test-database' ] |
獲取一個Collection
一個collection指一組存在MongoDB中的檔案,大致可以認為是關係型資料庫中表的概念。獲取Collection方法與獲取資料庫方法一致:
1
|
>>>
collection = db.test_collection |
或字典方式:
1
|
>>>
collection = db[ 'test-collection' ] |
需要強調的一點是,MongoDB裡的collection和資料庫都是惰性建立的 - 之前我們提到的所有命令實際沒有對MongoDB server
進行任何操作。直到第一個檔案插入後,才會建立。
檔案(Documents)
資料在MongoDb中是以JSON類檔案的形式儲存起來的。在PyMongo中用字典來代表檔案。例如,下面這個字典就可以代表一篇博文:
1
2
3
4
5
|
>>> import
datetime >>>
post = { "author" : "Mike" , ... "text" : "My
first blog post!" , ... "tags" :
[ "mongodb" , "python" , "pymongo" ], ... "date" :
datetime.datetime.utcnow()} |
注意,檔案裡可以儲存python原生型別(datetime.datetime
),這些型別的值會被自動在原生型別和BSON格式之間轉換。
檔案插入操作
要把一個檔案插入collection,可以使用insert()
方法:
1
2
3
4
|
>>>
posts = db.posts >>>
post_id = posts.insert(post) >>>
post_id ObjectId( '...' ) |
檔案被插入之後,如果檔案內沒有_id
這個鍵值,那麼系統自動新增一個到檔案裡。這是一個特殊鍵值,它的值在整個collection裡是唯一的。insert()
返回這個檔案的_id
值。對這個值的更多內容,可以參考:the
documentation on _id。
插入第一個檔案後,這個posts collection 就真實的在server上建立了。可以通過檢視資料庫上的所有collection來驗證:
1
2
|
>>>
db.collection_names() [u 'system.indexes' ,
u 'posts' ] |
這個名為 system.indexes的 collection是個特殊的內部collection,這是自動建立的。
單個檔案獲取 find_one()
MongoDB中最基本的查詢就是find_one
。這個函式返回一個符合查詢的檔案,或者在沒有匹配的時候返回None。這在你知道只有一個檔案符合條件的時候,或者只對第一個符合條件的檔案感興趣的時候,很有用。下面用 find_one()
來獲取 posts collection裡的第一個檔案:
1
2
|
>>>
posts.find_one() {u 'date' :
datetime.datetime(...), u 'text' :
u 'My
first blog post!' ,
u '_id' :
ObjectId( '...' ),
u 'author' :
u 'Mike' ,
u 'tags' :
[u 'mongodb' ,
u 'python' ,
u 'pymongo' ]} |
返回結果是一個我們之前插入的符合條件的字典型別值。
注意,返回的檔案裡已經有了_id
這個鍵值,這是自動新增的。
find_one()
還支援對特定元素進行匹配的查詢。篩選出作者是“Mike”的檔案:
1
2
|
>>>
posts.find_one({ "author" : "Mike" }) {u 'date' :
datetime.datetime(...), u 'text' :
u 'My
first blog post!' ,
u '_id' :
ObjectId( '...' ),
u 'author' :
u 'Mike' ,
u 'tags' :
[u 'mongodb' ,
u 'python' ,
u 'pymongo' ]} |
如果換個作者名,像 “Eliot”,就查不到結果:
1
2
|
>>>
posts.find_one({ "author" : "Eliot" }) >>> |
按照ObjectId查詢
通過_id
也可以進行查詢, 在例子中就是ObjectId:
1
2
3
4
|
>>>
post_id ObjectId(...) >>>
posts.find_one({ "_id" :
post_id}) {u 'date' :
datetime.datetime(...), u 'text' :
u 'My
first blog post!' ,
u '_id' :
ObjectId( '...' ),
u 'author' :
u 'Mike' ,
u 'tags' :
[u 'mongodb' ,
u 'python' ,
u 'pymongo' ]} |
注意 ObjectId 並不等價於他的字串形式。
1
2
3
|
>>>
post_id_as_str = str(post_id) >>>
posts.find_one({ "_id" :
post_id_as_str}) # No result >>> |
web應用的一個常見任務就是在requset的URL裡獲取ObjectId然後找到與之匹配的檔案。在本例中,必須要先從字串轉換為ObjectId然後傳給find_one:
1
2
3
4
5
6
|
from
bson.objectid import
ObjectId #
框架從URL裡獲取post_id,然後把他作為字串傳入 def
get(post_id): #
從字串轉換為ObjectId: document
= client.db.collection.find_one({ '_id' :
ObjectId(post_id)}) |
與這個話題相關的文章:When I query for a document by ObjectId in my web application I get no result
關於Unicode字串的一點說明
你可能已經注意到,之前存入資料庫的事常規的Python字串,這與我們從資料庫伺服器裡取回來的看起來不同(比如 u’Mike’ 而不是‘Mike’)。下面簡單解釋一下。
MongoDB 以格式儲存資料. BSON 字串都是 UTF-8編碼的, 所以PyMongo必須確保它儲存的字串值包含有效地 UTF-8資料.常規字串 ( )都是有效的,可以不改變直接儲存。Unicode 字串( )就需要先編碼成 UTF-8 格式.例子裡的字串顯示為u’Mike’ 而不是 ‘Mike’是因為 PyMongo 會把每個BSON 字串轉換成 Python 的unicode 字串, 而不是常規的 str.
批量插入
為了讓查詢更有趣點,我們多插入幾個檔案。除了單個檔案插入,也可以通過給insert()
方法傳入可迭代的物件作為第一個引數,進行批量插入操作。這將會把迭代表中的每個檔案插入,而且只向server傳送一條命令:
1
2
3
4
5
6
7
8
9
10
|
>>>
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 )}] >>>
posts.insert(new_posts) [ObjectId( '...' ),
ObjectId( '...' )] |
這個例子裡有一些比較有趣的地方:
insert()
現在返回兩個ObjectId例項,每個代表一個插入的檔案。
new_posts[1]
與其他的posts內容格式不相同:裡面沒有"tags”,另外我們增加了一個新的“title”域。這就是MongoDB所提到的無schema特點。
查詢多個檔案
想獲取多個檔案的時候,可以使用find()
方法。find()
返回一個
Cursor 例項,通過它我們可以便利每個符合查詢條件的檔案。比如便利每個 posts collection裡的檔案:
1
2
3
4
5
6
|
>>> for
post in posts.find(): ...
post ... {u 'date' :
datetime.datetime(...), u 'text' :
u 'My
first blog post!' ,
u '_id' :
ObjectId( '...' ),
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( '...' ),
u 'author' :
u 'Mike' ,
u 'tags' :
[u 'bulk' ,
u 'insert' ]} {u 'date' :
datetime.datetime( 2009 , 11 , 10 , 10 , 45 ),
u 'text' :
u 'and
pretty easy too!' ,
u '_id' :
ObjectId( '...' ),
u 'author' :
u 'Eliot' ,
u 'title' :
u 'MongoDB
is fun' } |
與使用find_one()
時候相同,可以傳入一個檔案來限制查詢結果。比如查詢所有作者是 “Mike”的文章:
1
2
3
4
5
|
>>> for
post in posts.find({ "author" : "Mike" }): ...
post ... {u 'date' :
datetime.datetime(...), u 'text' :
u 'My
first blog post!' ,
u '_id' :
ObjectId( '...' ),
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( '...' ),
u 'author' :
u 'Mike' ,
u 'tags' :
[u 'bulk' ,
u 'insert' ]} |
Counting
如果只想知道符合查詢條件的檔案有多少,可以用count()
操作,而不必進行完整的查詢。查詢collection的檔案總數:
1
2
|
>>>
posts.count() 3 |
或者只是特定的一些檔案:
1
2
|
>>>
posts.find({ "author" : "Mike" }).count() 2 |
限定範圍的查詢
MongoDB 支援多種高階查詢。例如,查詢晚於某個特定時間的post,結果按作者名排序:
1
2
3
4
5
6
|
>>>
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 'and
pretty easy too!' ,
u '_id' :
ObjectId( '...' ),
u 'author' :
u 'Eliot' ,
u 'title' :
u 'MongoDB
is fun' } {u 'date' :
datetime.datetime( 2009 , 11 , 12 , 11 , 14 ),
u 'text' :
u 'Another
post!' ,
u '_id' :
ObjectId( '...' ),
u 'author' :
u 'Mike' ,
u 'tags' :
[u 'bulk' ,
u 'insert' ]} |
這裡使用了特殊的”$lt"操作符來進行範圍查詢,並呼叫sort()
對結果按照作者排序。
索引(Indexing)
為了讓上述查詢更快一點,可以新增一個在"date” 和 “author"上新增複合索引。首先,使用explain()
方法來了解查詢在沒有新增索引情況下如何執行:
1
2
3
4
|
>>>
posts.find({ "date" :
{ "$lt" :
d}}).sort( "author" ).explain()[ "cursor" ] u 'BasicCursor' >>>
posts.find({ "date" :
{ "$lt" :
d}}).sort( "author" ).explain()[ "nscanned" ] 3 |
可以看道,查詢使用的是BasicCursor
,而且掃描了全部的三個檔案。現在新增一個複合索引,再看看同樣的操作:
1
2
3
4
5
6
7
|
>>>
from pymongo import
ASCENDING, DESCENDING >>>
posts.create_index([( "date" ,
DESCENDING), ( "author" ,
ASCENDING)]) u 'date_-1_author_1' >>>
posts.find({ "date" :
{ "$lt" :
d}}).sort( "author" ).explain()[ "cursor" ] u 'BtreeCursor
date_-1_author_1' >>>
posts.find({ "date" :
{ "$lt" :
d}}).sort( "author" ).explain()[ "nscanned" ] 2 |
現在查詢使用的是BtreeCursor
(利用這個索引),並且只掃描了兩個符合條件的檔案。
關於索引可以檢視MongoDB的文件indexs.
來自:http://my.oschina.net/zanyang1103/blog/337142
相關文章
- 【Python】pymongo連結mongoPythonGo
- MongoDB 及 PyMongo 的基本用法MongoDB
- MongoDB和pymongo自用手冊MongoDB
- Python 全棧系列44 - pymongo的基本使用Python全棧Go
- Python安裝PyMongo的方法詳細介紹PythonGo
- MongoDB Python官方驅動 PyMongo 的簡單封裝MongoDBPython封裝
- Python3中使用PyMongo的方法詳解PythonGo
- Python全棧MongoDB資料庫(聚合、二進位制、GridFS、pymongo模組)Python全棧MongoDB資料庫
- 杜教篩入門
- [Python] 透過pymongo連線docker中並開啟了副本集的mongodb資料庫PythonDockerMongoDB資料庫
- lxml官方入門教程(The lxml.etree Tutorial)翻譯XML
- 【冷啟動#2】實用的springboot tutorial入門demoSpring Boot
- Node.js入門教學之一Node.js
- 新手請教,遊戲入門程式 c遊戲
- 第1章 1.1Deluxe APP快速入門——剪輯入門教學UXAPP
- Arduino :入門教學讓你輕鬆玩轉UI
- Leaflet入門:新增點線面並匯入GeoJSON資料|Tutorial of Leaflet: Adding Points, Lines, Polygons and Import GeoJSON FileJSONGoImport
- Zeiss tutorial
- Pytorch | Tutorial-07 儲存和載入模型PyTorch模型
- WordPress 是什麼?TechMoon 科技月球 - 新手入門教學
- 「端外商城」入門教學1.0:最低成本做好基建
- simvison tutorial pdf
- Batch Scripting TutorialBAT
- 《MySQL 8從入門到精通(視訊教學版)》簡介MySql
- RabbitMQ tutorial - "Hello world!"MQ
- 面向前端的 Lottie & AE 動畫手把手入門教學前端動畫
- 《Vue 3.x從入門到精通(影片教學版)》簡介Vue
- 《MySQL 8.x從入門到精通(影片教學版)》簡介MySql
- SEO新手初入門,認識什麼是SEO教學 Read more at TechMoon
- linux symbolic link attack tutorialLinuxSymbol
- [譯]A Simple CSS Animation TutorialCSS
- 上門健身私教,上門健身教練,上門教練APP小程式系統原始碼開發APP原始碼
- 《SQL Server 2019從入門到精通(視訊教學超值版)》簡介SQLServer
- 入門入門入門 MySQL命名行MySql
- pygame 教學 匯入圖片GAM
- Tutorial: Create SQL Cluster(FCI) on RHELSQL
- Tutorial: Add a node to SQL cluster on RHELSQL
- Hive Tutorial 閱讀記錄Hive
- 《前端圖形學從入門到放棄》002 教練我想學矩陣前端矩陣