python - pymongo 中的快速或批量更新

如何在 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/

相关文章:

Mongodb - 删除数组字段中所有元素的正确方法?

node.js - 当 mongodb 的好处应该是无模式时,为什么 mongoose 使用模式?

node.js - 想要弄清楚NodeJS应用程序结构(完整的JavaScript堆栈)

javascript - 如果 .find() mongoose 没有找到任何东西,请执行某些操作

ruby-on-rails - Mongoid 查找器不起作用?

node.js - 同步连接mongodb

node.js - Node.js 上 MongoDB 连接的最佳实践是什么?

mongodb - 如何使用 Meteor Upsert

mongodb - node.js 的 mongoose 中的十进制/ float

mongodb - 在 mongodb 中删除重复文档的最快方法