gpt4 book ai didi

python - pymongo 需要超过 24 小时才能循环遍历 20 万条记录

转载 作者:可可西里 更新时间:2023-11-01 09:46:32 24 4
gpt4 key购买 nike

我在数据库中有两个集合 pagepagearchive我正在尝试清理。我注意到在 pagearchive 中创建了新文档而不是按预期向嵌入式文档添加值。所以基本上这个脚本所做的是遍历 page 中的每个文档。然后在 pagearchive 中找到该文档的所有副本并将我想要的数据移动到一个文档中并删除了额外的内容。

问题是 pagearchive 中只有 200K 个文档根据我在底部打印的计数变量,迭代 1000 条记录需要 30 分钟到 60 分钟以上的时间。这非常慢。我见过的重复文档中最大的计数是 88。但在大多数情况下,当我在 pageArchive 中查询时在 uu ,我看到 1-2 个重复文档。

mongodb 在具有 16GB RAM 的单实例 64 位机器上。 uupageArchive 上迭代的键集合是一个字符串。我确保该字段上有一个索引 db.pagearchive.ensureIndex({uu:1})我也做了 mongod --repair很好的衡量标准。

我猜问题出在我草率的 python 代码(不是很擅长),或者可能是我遗漏了 mongodb 所必需的东西。为什么它会这么慢,或者我可以做些什么来显着加快它的速度?

我想可能是因为 uu field 是一个字符串,它导致了瓶颈,但这是文档中的唯一属性(或者一旦我清理了这个集合就会是)。最重要的是,当我停止进程并重新启动它时,它每秒可以加速约 1000 条记录。直到它开始再次在集合中找到重复项,然后它再次变慢(每 10-20 分钟删除大约 100 条记录)

from pymongo import Connection
import datetime


def match_dates(old, new):
if old['coll_at'].month == new['coll_at'].month and old['coll_at'].day == new['coll_at'].day and old['coll_at'].year == new['coll_at'].year:
return False

return new

connection = Connection('dashboard.dev')


db = connection['mydb']

pageArchive = db['pagearchive']
pages = db['page']

count = 0
for page in pages.find(timeout=False):

archive_keep = None
ids_to_delete = []
for archive in pageArchive.find({"uu" : page['uu']}):

if archive_keep == None:
#this is the first record we found, so we will store data from duplicate records with this one; delete the rest
archive_keep = archive
else:
for attr in archive_keep.keys():
#make sure we are dealing with an embedded document field
if isinstance(archive_keep[attr], basestring) or attr == 'updated_at':
continue
else:
try:
if len(archive_keep[attr]) == 0:
continue
except TypeError:
continue
try:
#We've got our first embedded doc from a property to compare against
for obj in archive_keep[attr]:
if archive['_id'] not in ids_to_delete:
ids_to_delete.append(archive['_id'])
#loop through secondary archive doc (comparing against the archive keep)
for attr_old in archive.keys():
#make sure we are dealing with an embedded document field
if isinstance(archive[attr_old], basestring) or attr_old == 'updated_at':
continue
else:
try:
#now we know we're dealing with a list, make sure it has data
if len(archive[attr_old]) == 0:
continue
except TypeError:
continue
if attr == attr_old:
#document prop. match; loop through embedded document array and make sure data wasn't collected on the same day
for obj2 in archive[attr_old]:
new_obj = match_dates(obj, obj2)
if new_obj != False:
archive_keep[attr].append(new_obj)
except TypeError, te:
'not iterable'
pageArchive.update({
'_id':archive_keep['_id']},
{"$set": archive_keep},
upsert=False)
for mongoId in ids_to_delete:
pageArchive.remove({'_id':mongoId})
count += 1
if count % 100 == 0:
print str(datetime.datetime.now()) + ' ### ' + str(count)

最佳答案

我将对代码进行以下更改:

  • match_dates 中返回 None 而不是 False 并执行 if new_obj is not None: 它将检查引用,而不调用对象 __ne____nonzero__

  • for page in pages.find(timeout=False): 如果只使用uu键并且页面很大,fields=[' uu'] find 的参数应该可以加速查询。

  • archive_keep == Nonearchive_keep is None

  • archive_keep[attr] 被调用了 4 次。保存 keep_obj = archive_keep[attr] 然后使用 keep_obj 会快一点。

  • ids_to_delete = [] 更改为 ids_to_delete = set()。然后 if archive['_id'] not in ids_to_delete: 将是 O(1)

关于python - pymongo 需要超过 24 小时才能循环遍历 20 万条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9241216/

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