我使用Riot API for League of Legends来制作Python。我有一个集合,它只是我没有从API中提取的匹配游戏的ID,另一个是拉动的matchmade游戏。总的来说,我目前有94,040个拉出的比赛和224,346个比赛ID,我还没有拉过。
在我的代码中,我正在查看人员的个人资料以获取新的匹配ID,以便在我将其添加到尚未提取的ID集合之前添加我已经拥有的匹配项。通过第二个collection.find每次迭代需要大约7秒钟,我不知道为什么。我将这两个集合编入索引,当我使用collection.find({}).sort({})时,由于某种原因实际上需要更长的时间。
这是我的代码:
import pymongo
import time
client = pymongo.MongoClient('mongodb://localhost')
match_db = client.matched_games
summoner_db = client.summoner_match_history
match_id_db = client.match_id
matches = match_db.matches
summoners = summoner_db.summoners
match_id = match_id_db.match
def main():
for matchid in summoners.find({}, {'matches.gameId': 1, '_id': 0}, no_cursor_timeout=True):
timer = time.time()
try:
for match in matchid['matches']:
print(match)
match = match['gameId']
for k in matches.find({}):
k = k['gameId']
if k == match:
print(time.time() - timer)
timer = time.time()
print('Already have match #' + str(k))
break
else:
print(time.time() - timer)
timer = time.time()
print('Inserting match #' + str(match) + '.')
match_id.insert({'match_id': match})
except KeyError as e:
print(e)
pass
except pymongo.errors.DuplicateKeyError as e:
# print(e)
pass
if __name__ == '__main__':
main()
答案 0 :(得分:1)
不是一次一个地遍历所有这些,而是可以执行以下查询:
if matches.find('game_id': 'match_id').count() == 0 //Match does not exist in the database.
所以你让数据库返回匹配集合中的每个文档,我认为这个数据库有~95,000个条目(如果我错了,请纠正我),然后遍历每个文档以检查id是否已经存在。这意味着:
所以你要迭代〜190,000次,这不包括你的程序存储和获取数据库结果的所有开销,以便你迭代。
但是,通过使用matches.find().count()
,您将使数据库索引适合您。数据库可以使用其索引来查看您尝试查找的内容是否存在得更快,而不是按顺序遍历所有95,000个文档。此外,一旦数据库返回.count()
的值,您就不必再迭代95,000次,因为您只需要一个if语句来查看该值是0还是1.这样可以节省迭代次数并减少开销您的程序显着,从而加快执行速度。
我不确定是否已经说得那么清楚了,所以请在评论中提问,以确保你完全理解发生了什么。