簡體   English   中英

MongoDB優化多個find_one +在循環內插入

[英]MongoDB optimize multiple find_one + insert inside loop

我正在將MongoDB 4.0.1和Pymongo與pyhton 3.5一起使用。 我必須每30-60秒循環遍歷12000個項目,並將新數據添加到MongoDB中。 對於此示例,我們將討論用戶,寵物和汽車。 用戶可以獲得1輛汽車和1只寵物。

我需要pet ObjectID和car ObjectID來創建我的用戶,因此我必須在循環中一個接一個地添加它們,這非常慢。 查找現有數據大約需要25秒鍾,如果不存在則添加它們。

while dictionary != False:
    # Create pet if not exist
    existing_pet = pet.find_one({"code": dictionary['pet_code']})

    if bool(existing_pet):
        pet_id = existing_pet['_id']
    else:
        pet_id = pet.insert({
            "code" : dictionary['pet_code'],
            "name" : dictionary['name']
        })
        # Call web service to create pet remote

    # Create car if not exist
    existing_car = car.find_one({"platenumber": dictionary['platenumber']})

    if bool(existing_car):
        car_id = existing_car['_id']
    else:
        car_id = car.insert({
            "platenumber" : dictionary['platenumber'],
            "model" : dictionary['model'],
            "energy" : 'electric'
        })
        # Call web service to create car remote

    # Create user if not exist
    existing_user = user.find_one(
        {"$and": [
            {"user_code": dictionary['user_code']},
            {"car": car_id},
            {"pet": pet_id}
        ]}
    )

    if not bool(existing_user):
        user_data.append({
            "pet" : pet_id,
            "car" : car_id,
            "firstname" : dictionary['firstname'],
            "lastname" : dictionary['lastname']
        })
        # Call web service to create user remote

# Bulk insert user
if user_data:
    user.insert_many(user_data)

我為用於find_one的每一列創建了索引:

db.user.createIndex( { user_code: 1 } )
db.user.createIndex( { pet: 1 } )
db.user.createIndex( { car: 1 } )
db.pet.createIndex( { pet_code: 1 }, { unique: true }  )
db.car.createIndex( { platenumber: 1 }, { unique: true }  )

有沒有辦法加快這個循環? 有什么聚集的東西或其他東西可以幫助我? 或者也許是我想要做的另一種方式?

我願意接受所有建議。

不要執行12000 find_one查詢,而是執行1個查詢以使用$ in運算符將所有存在的查詢帶入。 代碼類似於:

pet_codes = []
pet_names = []
while dictionary != False:
    pet_codes.append(dictionary['pet_code'])
    pet_names.append(dictionary['pet_name'])

pets = dict()
for pet in pet.find({"code": {$in: pet_codes}}):
    pets[pet['code']] = pet

new_pets = []
for code, name in zip(pet_codes, pet_names):
    if code not in pets:
        new_pets.add({'pet_code': code, 'name': name})

pet.insert_many(new_pets)

由於您已經在pet_code上建立了一個索引使其成為唯一索引,因此我們可以做得更好:只需嘗試將它們全部插入,因為如果我們嘗試插入一個現有的索引,則該記錄將出現錯誤,但是其余的將通過使用ordered =來成功來自文檔的錯誤:

new_pets = []
while dictionary != False:
    new_pets.add({
        "code" : dictionary['pet_code'],
        "name" : dictionary['name']
    })
pet.insert_many(new_pets, ordered=False)

如果您沒有唯一的限制集,則另一種方法是批量操作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM