更好的方式來處理這個問題,也有「插入/更新」許多文件以有效的方式是使用Bulk Operations API提交的所有信息在「批」與所有的effecient發送和接收的「奇迴應」確認。
這可以通過兩種方式處理。
首先忽略主鍵或其他指標的任何「重複錯誤」,那麼你可以使用「無序」的形式操作:
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=False)
for doc in docs:
bulk.insert(doc)
response = bulk.execute()
的「無序」或false
說法存在,使得運營都可以以任何順序執行,並且「完整」批處理將完成,只是在響應中「報告」任何實際錯誤。所以這是一種基本上「忽略」重複和移動的方法。
的另一種方法是大致相同,但使用與$setOnInsert
沿着「更新插入」功能性:
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=True)
for doc in docs:
bulk.find({ "_id": doc["_id"] }).upsert().updateOne({
"$setOnInsert": doc
})
response = bulk.execute()
由此.find()
「查詢」部分用於查詢爲一個文件,使用存在的「主鍵「或備選地文檔的」唯一鍵「。如果找不到匹配,則在創建新文檔時會出現「upsert」。由於所有修改內容都在$setOnInsert
之內,因此只有在發生「upsert」時纔會修改文檔字段。否則,在文件「匹配」的情況下,對於保存在該操作員下的數據,實際上沒有任何變化。
在這種情況下,「有序」意味着每個語句實際上是以它創建的「相同」順序提交的。此外,任何「錯誤」都會停止更新(在發生錯誤的位置),以便沒有更多的操作會被執行。它是可選的,但可能建議用於正常的「重複」行爲,其中後面的語句「複製」前一個數據。
因此,爲了更有效的寫入,總體思路是使用「Bulk」API並相應地構建您的操作。這裏的選擇實際上取決於來源的「插入順序」是否對您很重要。
當然,"ordered"=False
操作適用於insert_many
,它實際上在較新的驅動程序版本中使用「批量」操作。但通過使用簡單的API可以「混合」操作的通用界面,您將獲得更大的靈活性。
Gotcha。因此,使用帶有「ordered」= False的insert_many將繼續運行所有插入,而忽略可能彈出的任何錯誤? – SLee
@SLee它應該。有些API已被「修改」,所以結果實際上會引發異常(以前不是這種情況),但「整個」批處理應該執行。另一方面,「upsert」選項不能拋出異常(來自重複鍵),因爲它並不意味着它的任何操作錯誤。正如我所說,*「關鍵在於操作順序是否重要」*。 –