PyMongo官方文档翻译——VNPY
PyMongo是MongoDB數據庫的python模塊
VNPY默認的數據庫,沒有采用SQL類型的數據庫,而是采用No-Sql類型的MongoDB數據庫,
對于想了解VNPY內部結構的童鞋,多多少少會遇到PyMongo的調用問題,雖然我個人不喜歡用數據庫的方式存儲證券行情數據,這類高度結構化的數據,但為了重構VNPY,使得使用HDF5或CSV代替MongoDB,我們還是需要了解一下該數據庫的調用方式,下面就給大家獻上一篇PyMongo的官方文檔的翻譯
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
本翻譯文檔包含以下內容:
- 使用PyMongo插入數據
- 使用PyMongo查詢數據
- 使用PyMongo更新數據
- 使用PyMongo刪除數據
- 使用PyMongo進行數據聚合
- 使用PyMongo創建索引
原文地址鏈接:https://docs.mongodb.com/manual/introduction/
PyMongo是一個用于MongoDB的Python工具,也是一個被推薦的Python操作MongoDB數據庫的方式。
使用步驟
安裝PyMongo
Linux或者OS X系統
你可以只用pip工具安裝:
pip install pymongoWindows系統下
使用Windows安裝工具,詳見https://pypi.python.org/pypi/pymongo/。
引入pymongo
在一個Python交互shell中完成此過程,或者也可以在其他Python環境中完成,例如Python腳本、Python模塊、Python項目。
從pymongo中引入MongoClicent。
from pymongo import MongoClient創建一個連接
使用MongoClient創建一個連接:
client = MongoClient()如果你沒有特別為MongoClient指定參數,MongoClient將使用MongoDB默認參數即localhost接口和27017端口。
你可以使用一個完整的MongoDB URI來定義連接:
client = MongoClient("mongodb://mongodb0.example.net:27019")這個MongoClient代表了一個運行于mongodb.example.net端口號為27019的MongoDB連接。
訪問數據庫對象
第一個你用pymongo來交互的基本類是Database,它代表了MongoDB中的數據庫(database)結構。數據庫保存了邏輯上相關的集合組。MongoDB將在第一次使用新的數據庫的時候自動創建它。
你可以使用屬性訪問的方式,賦值一個數據庫(例如名字為primer)給本地變量db,如下所示:
db = client.primer你也可以使用字典形式訪問一個數據庫,這會移除Python特有的命名限制,如下所示:
db = client['primer']訪問集合對象
第二個你將使用pymongo進行交互的基本類是Collection,它代表了MongoDB中的集合(collection)結構。集合(collection)保存了邏輯上相關的文檔組。
你可以直接使用字典形式訪問集合或者通過一個訪問一個數據庫對象的屬性來訪問集合,如下所示:
db.dataset db['dataset']你也可以給一個變量進行賦值,以在其他地方使用這個集合,如下所示:
coll = db.dataset coll = db['dataset']使用PyMongo插入數據
概覽
你可以使用insert_one()方法和insert_many()方法來向MongoDB的集合中插入文檔。如果你所插入的集合在MongoDB中不存在,MongoDB將為你自動創建一個集合。
先決條件
在Python命令行或者IDLE中,使用MongoClient連接一個正在運行的MongoDB實例,且已經打開test數據庫。
from pymongo import MongoClientclient = MongoClient() db = client.test插入一個文檔
向集合restaurants中插入一個文檔。如果集合不存在,這個操作將創建一個新的集合。
from datetime import datetime result = db.restaurants.insert_one({"address": {"street": "2 Avenue","zipcode": "10075","building": "1480","coord": [-73.9557413, 40.7720266]},"borough": "Manhattan","cuisine": "Italian","grades": [{"date": datetime.strptime("2014-10-01", "%Y-%m-%d"),"grade": "A","score": 11},{"date": datetime.strptime("2014-01-16", "%Y-%m-%d"),"grade": "B","score": 17}],"name": "Vella","restaurant_id": "41704620"} )這個操作返回了一個InsertOneResult對象,它包括了insert_id屬性表示被插入的文檔的_id。訪問insert_id的方式如下:
result.inserted_id你插入的文檔的ObjectId將和如下所示的不同。
ObjectId("54c1478ec2341ddf130f62b7")如果你傳遞給insert_one()方法的參數不包含_id字段,MongoClient將自動添加這個字段并且生成一個ObjectId設置為這個字段的值。
使用PyMongo查詢數據
概覽
你可以通過find()方法產生一個查詢來從MongoDB的集合中查詢到數據。MongoDB中所有的查詢條件在一個集合中都有一個范圍。
查詢可以返回在集合中的所有數據或者只返回符合篩選條件(filter)或者標準(criteria)的文檔。你可以在文檔中指定過濾器或者標準,并作為參數傳遞給find()方法。
find()方法返回一個查詢結果的游標,這是一個產生文檔的迭代對象。
先決條件
本示例中使用test數據庫中的restaurants集合。與使用示例數據填充集合有關的介紹請見Import Example Dataset。
在Python命令行或者IDLE中,使用MongoClient連接一個正在運行的MongoDB實例,且已經打開test數據庫。
from pymongo import MongoClientclient = MongoClient() db = client.test在一個集合中查詢所有文檔
調用find()方式不需要傳值即可得到集合中所有的文檔。舉例來說,如下所示的操作即是返回restaurants集合中所有文檔。
cursor = db.restaurants.find()迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果包含了所有restaurants集合中的所有文檔。
指定相等條件
對某一個字段的相等條件查詢有如下形式:
{ <field1>: <value1>, <field2>: <value2>, ... }如果字段(<field>)在某個文檔的某一個數組內,則使用點操作符(dot notation)去訪問該字段。
使用一個頂級字段進行查詢
如下所示的操作將查詢borough字段等于Manhattan的文檔。
cursor = db.restaurants.find({"borough": "Manhattan"})迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
在一個嵌入式的文檔中查詢
要指定嵌入文檔中的字段的查詢條件,需要使用點操作符。使用點操作符需要使用雙引號將字段名包裹。下面的操作將指定一個文檔的地址字典中的郵編字段的一個相等的條件。
cursor = db.restaurants.find({"address.zipcode": "10075"})迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
更多的關于嵌入式文檔的查詢條件信息,請參閱https://docs.mongodb.com/manual/tutorial/query-documents/#read-operations-subdocuments。
在一個數組中查詢
grades數組包含一個嵌入式文檔作為其元素。在該文檔的字段上指定一個相等條件需要用到點操作符。使用點操作符需要使用雙引號將字段名包裹。如下所示的查詢將查詢一個有嵌入式文檔的grades字段,該字段中的grade等于B。
cursor = db.restaurants.find({"grades.grade": "B"})迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
更多的關于數組內查詢條件的信息,例如數組中特殊的混合條件,請參閱Array及$elemMatch操作符。
使用操作符指定條件
MongoDB支持使用操作符指定查詢條件,例如比較操作符。雖然這其中有一些例外,例如$or和$and條件操作符。使用操作符進行查詢一般有如下形式:
{ <field1>: { <operator1>: <value1> } }完整的操作符列表請查閱query opeartors(http://docs.mongodb.org/manual/reference/operator/query)。
大于($gt)操作符
查詢字段grades包含一個嵌入式文檔,其中score大于30。
cursor = db.restaurants.find({"grades.score": {"$gt": 30}})迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
小于($lt)操作符
查詢字段grades包含一個嵌入式文檔,其中score小于10。
cursor = db.restaurants.find({"grades.score": {"$lt": 10}})迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
組合條件
你可以使用邏輯與(AND)或者邏輯或(OR)組合多個查詢條件。
邏輯與
你可以使用一個列表指定一個邏輯與條件查詢操作,使用逗號分隔條件。
cursor = db.restaurants.find({"cuisine": "Italian", "address.zipcode": "10075"}) bait_sessions = db_session.session.find({"$and":[{"classification_id":"pending"}, \{"bait_session.did_complete":True}]})?
迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
邏輯或
你可以使用$or操作符進行邏輯或條件的指定。
cursor = db.restaurants.find({"$or": [{"cuisine": "Italian"}, {"address.zipcode": "10075"}]})迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件的文檔。
對結果進行排序
要指定結果集的順序,可以通過追加sort()方法進行查詢。給sort()方法傳遞需要排序的字段和配需類型等。
- pymongo.ASCENDING表示升序排序。
- pymongo.DESCENDING表示降序排序。
如果要通過多個鍵星星排序,可以傳遞鍵的列表和以及對應的排序類型的列表。舉例來說,如下操作將返回restaurants集合中所有的文檔,并且先通過borough字段進行升序排序,然后在每個borough內,通過"address.zipcode"字段進行升序排序。
import pymongo cursor = db.restaurants.find().sort([("borough", pymongo.ASCENDING),("address.zipcode", pymongo.ASCENDING) ])迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將只包含符合條件且經過排序的文檔。
使用PyMongo更新數據
概覽
你可以使用update_one()和update_many方法更新集合中的文檔。update_one()方法一次更新一個文檔。使用update_many()方法可以更新所有符合條件的文檔。方法接受以下三個參數:
- 一個篩選器,可以對符合條件的文檔進行更新。
- 一個指定的修改語句
- 自定義更新時的操作參數
要指定更新時的過濾器,使用和查詢條件時相同的結構即可。參見使用PyMongo查詢數據獲取查詢條件的信息。
你不能更新_id字段。
先決條件
本示例中使用test數據庫中的restaurants集合。與使用示例數據填充集合有關的介紹請見Import Example Dataset。
在Python命令行或者IDLE中,使用MongoClient連接一個正在運行的MongoDB實例,且已經打開test數據庫。
from pymongo import MongoClientclient = MongoClient() db = client.test更新特定的字段
要改變一個特定字段的值,MongoDB提供了更新操作符,例如$set操作符可以修改值。例如$set之類的操作符將在沒有該字段的時候新建這個字段。可以查閱update operators作為參考。
更新頂級字段
如下操作將更新第一個符合name等于Juni這個條件的文檔。使用$set操作符更新cuisine字段且將lastModified修改為當前日期。
result = db.restaurants.update_one({"name": "Juni"},{"$set": {"cuisine": "American (New)"},"$currentDate": {"lastModified": True}} )這個操作返回了一個UpdateResult對象。這個對象報告了符合條件的文檔數目以及被修改的文檔數目。
要查看符合篩選器條件的文檔數目,通過訪問UpdateResult對象的matched_count屬性。
result.matched_countmatched_count值為:
1要查看更新操作中被修改的文檔數目,通過訪問UpdateResult對象的modified_count屬性。
modified_count值為:
1更新嵌入式文檔中的字段
要更新一個嵌入式文檔中的字段,需要使用點操作符。當使用點操作符時,使用點操作符需要使用雙引號將字段名包裹。下面的操作將更新address字段中的street值。
result = db.restaurants.update_one({"restaurant_id": "41156888"},{"$set": {"address.street": "East 31st Street"}} )這個操作返回了一個UpdateResult對象。這個對象報告了符合條件的文檔數目以及被修改的文檔數目。
要查看符合篩選器條件的文檔數目,通過訪問UpdateResult對象的matched_count屬性。
result.matched_countmatched_count值為:
1要查看更新操作中被修改的文檔數目,通過訪問UpdateResult對象的modified_count屬性。
modified_count值為:
1更新多個文檔
update_one()方法更新了一個文檔,要更新多個文檔,需要使用update_many()方法。下面的操作將更新所有的address.zipcode等于10016以及cuisine等于Other的文檔,將cuisine字段設置為Category To Be Determined以及將lastModified更新為當前日期。
result = db.restaurants.update_many({"address.zipcode": "10016", "cuisine": "Other"},{"$set": {"cuisine": "Category To Be Determined"},"$currentDate": {"lastModified": True}} )這個操作返回了一個UpdateResult對象。這個對象報告了符合條件的文檔數目以及被修改的文檔數目。
要查看符合篩選器條件的文檔數目,通過訪問UpdateResult對象的matched_count屬性。
result.matched_countmatched_count值為:
20要查看更新操作中被修改的文檔數目,通過訪問UpdateResult對象的modified_count屬性。
modified_count值為:
20替換一個文檔
要替換整個文檔(除了_id字段),將一個完整的文檔作為第二個參數傳給update()方法。替代文檔對應原來的文檔可以有不同的字段。在替代文檔中,你可以忽略_id字段因為它是不變的。如果你包含了_id字段,那它必須和原文檔的值相同。
重要:
在更新之后,該文檔將只包含替代文檔的字段。
在如下的更新操作后,被修改的文檔將只剩下_id、name和address字段。該文檔將不再包含restaurant_id、cuisine、grades以及borough字段。
result = db.restaurants.replace_one({"restaurant_id": "41704620"},{"name": "Vella 2","address": {"coord": [-73.9557413, 40.7720266],"building": "1480","street": "2 Avenue","zipcode": "10075"}} )replace_one操作返回了一個UpdateResult對象。這個對象報告了符合條件的文檔數目以及被修改的文檔數目。
要查看符合篩選器條件的文檔數目,通過訪問UpdateResult對象的matched_count屬性。
result.matched_countmatched_count值為:
20要查看更新操作中被修改的文檔數目,通過訪問UpdateResult對象的modified_count屬性。
modified_count值為:
20使用PyMongo刪除數據
概覽
你可以使用delete_one()以及delete_many()方法從集合中刪除文檔。方法需要一個條件來確定需要刪除的文檔。
要指定一個刪除條件,使用和查詢條件時相同的結構即可。參見使用PyMongo查詢數據獲取查詢條件的信息。
先決條件
本示例中使用test數據庫中的restaurants集合。與使用示例數據填充集合有關的介紹請見Import Example Dataset。
在Python命令行或者IDLE中,使用MongoClient連接一個正在運行的MongoDB實例,且已經打開test數據庫。
from pymongo import MongoClientclient = MongoClient() db = client.test步驟
刪除所有符合條件的文檔
下面的操作將刪除所有復合條件的文檔。
result = db.restaurants.delete_many({"borough": "Manhattan"})這個操作返回了一個DeleteResult對象。這個對象報告了被刪除的文檔數目。
要查看被刪除的文檔數目,通過訪問DeleteResult對象的deleted_count屬性。
result.deleted_countdeleted_count值為:
10259如果你已經插入或者更新了文檔,那么你得到的結果將和示例不同。
刪除所有文檔
要刪除一個集合中的所有文檔,給delete_many()方法傳遞一個空的條件參數即可。
result = db.restaurants.delete_many({})這個操作返回了一個DeleteResult對象。這個對象報告了被刪除的文檔數目。
要查看被刪除的文檔數目,通過訪問DeleteResult對象的deleted_count屬性。
result.deleted_countdeleted_count值為:
15100如果你已經插入或者更新了文檔,那么你得到的結果將和示例不同。
銷毀一個集合
刪除所有文檔的操作只會清空集合中的文檔。該集合以及集合的索引將依舊存在。要清空一個集合,銷毀該集合以及它的索引并且重建集合和索引可能是相比于清空一個集合更加高效的操作方式。使用drop()方法可以銷毀一個集合,包括它所有的索引。
db.restaurants.drop()使用PyMongo進行數據聚合
概覽
MongoDB可以進行數據聚合操作,例如可以針對某一字段進行分組或者對某一字段不同的值進行統計。
使用aggregate()方法可以使用基于步驟的聚合操作。appregate()方法接受多個數組作為每一步的操作。每一個階段按照順序處理,描述了對數據操作的步驟。
db.collection.aggregate([<stage1>, <stage2>, ...])先決條件
這部分的例子使用了test數據庫中的restaurants集合。需要查看在集合中填充的實例數據,請參閱Import Example Dataset。
在Python命令行或者IDLE中,使用MongoClient連接一個正在運行的MongoDB實例,且已經打開test數據庫。
from pymongo import MongoClientclient = MongoClient() db = client.test根據一個字段分組文件并計算總數
使用$group操作符去利用一個指定的鍵進行分組。在$group操作中,指定需要分組的字段為_id。$group通過字段路徑訪問字段,該字段需要有一個美元符號$作為前綴。$group操作可以使用累加器對本次分組進行計算。下面的例子將使用borough字段對restaurants集合進行操作,并且使用$sum累加器進行文檔的統計計算。
cursor = db.restaurants.aggregate([{"$group": {"_id": "$borough", "count": {"$sum": 1}}}] )迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將由如下文檔組成:
{u'count': 969, u'_id': u'Staten Island'} {u'count': 6086, u'_id': u'Brooklyn'} {u'count': 10259, u'_id': u'Manhattan'} {u'count': 5656, u'_id': u'Queens'} {u'count': 2338, u'_id': u'Bronx'} {u'count': 51, u'_id': u'Missing'}_id字段包含了不同的borough值,即根據鍵的值進行了分組。
篩選并分組文檔
使用$match操作來刪選文檔。$match使用MongoDB查詢語法。下面的管道使用$match來對restaurants進行一個borough等于"Queens"且cuisine等于Brazilian的查詢。接著$group操作對命中的文檔使用address.zipcode字段分組并使用$sum進行統計。$group通過字段路徑訪問字段,該字段需要有一個美元符號$作為前綴。
cursor = db.restaurants.aggregate([{"$match": {"borough": "Queens", "cuisine": "Brazilian"}},{"$group": {"_id": "$address.zipcode", "count": {"$sum": 1}}}] )迭代游標(cursor)并且打印文檔內容。
for document in cursor:print(document)結果將由如下文檔組成:
{u'count': 1, u'_id': u'11368'} {u'count': 3, u'_id': u'11106'} {u'count': 1, u'_id': u'11377'} {u'count': 1, u'_id': u'11103'} {u'count': 2, u'_id': u'11101'}_id字段包含了不同的zipcode值,即根據鍵的值進行了分組。
PyMongo上的索引
概覽
索引可以對查詢的高效執行起到支持。如果沒有索引,MongoDB必須進行全表掃描,即掃描集合中的每個文檔,來選擇符合查詢條件的文檔。如果一個適當的索引存在于一個查詢中,MongoDB可以使用索引限制必須檢查文檔的數量。
使用create_index()方法來為一個集合創建索引。所以可以對查詢的高效執行起到支持。MongoDB會在創建文檔的時候自動為_id字段創建索引。
要為一個或多個字段創建索引,使用一個包含字段和索引類型的列表作為參數:
[ ( <field1>: <type1> ), ... ]- 要創建一個升序的索引,指定pymongo.ASCENDING為索引類型()。
- 要創建一個降序的索引,指定pymongo.DESCENDING為索引類型()。
create_index()只會在索引不存在的時候創建一個索引。
先決條件
下面的例子將使用test數據庫中的restaurants集合。需要查看在集合中填充的實例數據,請參閱Import Example Dataset。
在Python命令行或者IDLE中,使用MongoClient連接一個正在運行的MongoDB實例,且已經打開test數據庫。
from pymongo import MongoClientclient = MongoClient() db = client.test創建一個單字段索引
在restaurants集合中的cuisine字段上創建自增的索引。
import pymongo db.restaurants.create_index([("cuisine", pymongo.ASCENDING)])該方法將返回被創建的索引的名字。
"u'cuisine_1'"創建一個復合索引
MongoDB支持在多個字段上創建符合索引。這幾個字段的命令將聲明這個索引包含的鍵。舉個例子,下面的操作將在cuisine字段和address.zipcode字段上創建一個復合索引。該索引將先對cuisine的值輸入一個升序的命令,然后對address.zipcode的值輸入一個降序命令。
import pymongo db.restaurants.create_index([("cuisine", pymongo.ASCENDING),("address.zipcode", pymongo.DESCENDING) ])該方法將返回被創建的索引的名字。
"u'cuisine_1_address.zipcode_-1'"?
總結
以上是生活随笔為你收集整理的PyMongo官方文档翻译——VNPY的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python爬虫之pyppeteer的使
- 下一篇: ORB-SLAM介绍(无源码版本)