gpt4 book ai didi

python - 对 MongoDB 实例中的每个文档执行操作

转载 作者:可可西里 更新时间:2023-11-01 10:51:32 25 4
gpt4 key购买 nike

我有一个包含 150 万个文档的 mongoDB 集合,所有文档都有相同的字段,我想取字段 A 的内容(每个文档都是唯一的)并执行 f(A),然后创建并填充字段 B。Python 中的伪代码:

for i in collection.find():
x = i**2
collection.update(i,x) #update i with x

注意:我知道更新代码可能是错误的,但除非它影响运行速度,否则为了简单起见,我选择将其留在那里

问题是,这段代码真的很慢,主要是因为它可以在大约一秒钟内运行 1000 个文档,然后服务器切断光标大约一分钟,然后又允许另一个 1000 个。我想知道是否有什么方法可以优化这个操作,或者如果我遇到这个缓慢的瓶颈。

补充说明:

  1. 作为实验,我调整了batch_size,速度更快,但效率不高,仍然需要几个小时

  2. 我也知道 SQL 可能会更快地执行此操作,我使用 noSQL DB 的其他原因与此问题无关

  3. 实例在本地运行,因此就所有意图和目的而言,没有网络延迟

  4. 我看到了this问题,但它的答案并没有真正解决我的问题

最佳答案

数据库客户端往往从实际数据库事件中抽象出来,因此观察到的延迟行为可能具有欺骗性。很可能您在那段时间实际上在敲击数据库,但该事件对 Python 解释器都是隐藏的。

也就是说,您可以采取一些措施来减轻它的负担。

1) 为更新所基于的属性 A 建立索引。这将使它返回得更快。

2) 在您的find 调用中放置一个投影运算符:

for doc in collection.find(projection=['A']):

这将确保您只返回需要的字段,并且如果您已正确索引唯一的 A 属性,将确保您的结果完全来自非常快速的索引。

3) 使用更新运算符来确保您只需要发回新字段。与其发送整个文档,不如发送回字典:

{'$set': {'B': a**2}}

这将在每个文档中创建字段 B,而不会影响任何其他内容。

因此,整个 block 将如下所示:

for doc in collection.find(projection=['A', '_id']):
collection.update(filter={'_id': doc['_id']},
update={'$set': {'B': doc['A']**2}})

这应该会大大减少 Mongo 必须完成的工作,以及(目前与您无关的)网络流量。

关于python - 对 MongoDB 实例中的每个文档执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39431475/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com