我有两个mongodb,一个数据库urls
由收集url的spider使用。这个数据库相当大,而且大多只包含url。{},然后根据cd2使用的url生成第二个报告。你知道吗
我当前用于第二个脚本的代码检查urls
数据库中的url当前是否在posts
数据库中。如果posts
db不包含url,则表示程序仍需要为url生成报告。如果它存在,我们就跳过它。你知道吗
以下是数据库循环:
for document in urls.find():
url = document['url'].split('.')[1]
if posts.find({'url': url}).count() == 0:
print(url, " url not found in posts, generating a new report")
try:
get_report(url, posts)
...
起初,这似乎是一个简单的解决办法。但是,在posts
db中填充了超过50000个报告之后,这个循环需要几个小时才能开始。你知道吗
有没有更快/更有效的方法来执行此循环?我在用python3和pymongo。你知道吗
此外,脚本现在由于pymongo.errors.CursorNotFound: cursor id '…'
错误而崩溃。我相信这意味着我需要将批量大小设置为一个较低的值。然而,这只是强化了我的信念,即这个循环的某些方面是极其低效的。你知道吗
迭代巨大的集合和搜索每个文档对于任何数据库都是非常昂贵的。你知道吗
通用解决方案:添加一些标志/机制以仅处理新的URL。(作者:威利斯)
解决方案1:批量搜索(
$in
)。如果你搜索(比如说每find
100个url),它会增加你的程序(x100):现在,您需要检查
URL
中不存在的内容。你知道吗解决方案2:(仅当相同的DB时)使用$lookup。
您需要添加一些索引,它就做到了(MongoDB本机实现比手动实现更快)。你知道吗
顺便问一下:您是指(相同|不同)服务器中的两个不同数据库还是同一数据库中的两个集合?你知道吗
如果
urls.find():
找到集合中的所有文档并对其进行循环,那么随着集合的增大,它不可避免地会减慢速度。你知道吗当你看到并创建了必要的文章时,你能用已处理的
true
标记你的已处理文档的url吗?这样,您就可以改为urls.find({processed: {$ne: true}})
只查找需要处理的url。使用此方案,您希望在url集合的{processed: 1}
上有一个索引,在posts集合的{url: 1}
上有一个索引。你知道吗这个怎么样:
这实际上是在内存中加载所有内容。如果你没有足够的内存,尝试任意散列你的网址和处理一个接一个。你知道吗
相关问题 更多 >
编程相关推荐