如何在 pymongo 中进行批量更新插入?我想更新一堆条目,一次做一个非常慢。
几乎相同的问题的答案在这里:Bulk update/upsert in MongoDB?
接受的答案实际上并没有回答问题。它只是提供了 mongo CLI 的链接以进行导入/导出。
我也愿意解释为什么做批量 upsert 是不可能的/不是最佳实践,但请解释解决此类问题的首选解决方案是什么。
最佳答案
现代版本的 pymongo(大于 3.x)将批量操作包装在一致的接口(interface)中,该接口(interface)会在服务器版本不支持批量操作的情况下降级。这在 MongoDB 官方支持的驱动程序中现在是一致的。
所以编码的首选方法是使用bulk_write()
相反,您使用 UpdateOne
其他适当的操作 Action 代替。现在当然首选使用自然语言列表而不是特定的构建器
旧文档的直接翻译:
from pymongo import UpdateOne
operations = [
UpdateOne({ "field1": 1},{ "$push": { "vals": 1 } },upsert=True),
UpdateOne({ "field1": 1},{ "$push": { "vals": 2 } },upsert=True),
UpdateOne({ "field1": 1},{ "$push": { "vals": 3 } },upsert=True)
]
result = collection.bulk_write(operations)
或者经典的文档转换循环:
import random
from pymongo import UpdateOne
random.seed()
operations = []
for doc in collection.find():
# Set a random number on every document update
operations.append(
UpdateOne({ "_id": doc["_id"] },{ "$set": { "random": random.randint(0,10) } })
)
# Send once every 1000 in batch
if ( len(operations) == 1000 ):
collection.bulk_write(operations,ordered=False)
operations = []
if ( len(operations) > 0 ):
collection.bulk_write(operations,ordered=False)
返回结果为BulkWriteResult
这将包含匹配和更新文档的计数器以及发生的任何“更新插入”的返回 _id
值。
对于批量操作数组的大小存在一些误解。发送到服务器的实际请求不能超过 16MB BSON 限制,因为该限制也适用于发送到使用 BSON 格式的服务器的“请求”。
但是,这并不能控制您可以构建的请求数组的大小,因为实际操作无论如何只会以 1000 个批处理发送和处理。唯一真正的限制是这 1000 条操作指令本身实际上并不会创建大于 16MB 的 BSON 文档。这确实是一项艰巨的任务。
批量方法的一般概念是“减少流量”,因为一次发送许多东西并且只处理一个服务器响应。减少附加到每个更新请求的开销可以节省大量时间。
https://stackoverflow.com/questions/5292370/