如何加速这个PyMongo查询/循环

时间:2017-08-23 23:17:14

标签: python mongodb pymongo

我使用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()

1 个答案:

答案 0 :(得分:1)

不是一次一个地遍历所有这些,而是​​可以执行以下查询:

if matches.find('game_id': 'match_id').count() == 0 //Match does not exist in the database.

所以你让数据库返回匹配集合中的每个文档,我认为这个数据库有~95,000个条目(如果我错了,请纠正我),然后遍历每个文档以检查id是否已经存在。这意味着:

    数据库
  1. ~95,000次迭代
  2. 〜95,​​000次迭代,程序检查匹配的标识
  3. 所以你要迭代〜190,000次,这不包括你的程序存储和获取数据库结果的所有开销,以便你迭代。

    但是,通过使用matches.find().count(),您将使数据库索引适合您。数据库可以使用其索引来查看您尝试查找的内容是否存在得更快,而不是按顺序遍历所有95,000个文档。此外,一旦数据库返回.count()的值,您就不必再迭代95,000次,因为您只需要一个if语句来查看该值是0还是1.这样可以节省迭代次数并减少开销您的程序显着,从而加快执行速度。

    我不确定是否已经说得那么清楚了,所以请在评论中提问,以确保你完全理解发生了什么。