Я использую Python 3, Pymongo с mongodb 4.0 и Ifxpy для запроса базы данных Informix.У меня есть 4 Коллекции в моей базе данных MongoDB:
- Пользователь
- Офис
- Домашнее животное
- Автомобиль
ОдинУ пользователя есть один офис, один питомец и один автомобиль.Итак, у меня есть 3 ссылки на каждое поле в коллекциях пользователей.
Мне нужно что-то вроде этого:
- Я хочу найти, есть ли пользователь с именем
John
идомашнее животное с именем Mickey
и автомобилем с моделью Tesla
и статусом inactive
.После этого я просто обновлю статус пользователя до active
.Мне нужно запросить Office, но я не использую его в этом примере.
Я создал индексы для каждого поля:
office.create_index([("code", pymongo.DESCENDING)], unique=True)
pet.create_index([("name", pymongo.DESCENDING)], unique=True)
car.create_index([("model", pymongo.DESCENDING)], unique=True)
user.create_index([("username", pymongo.DESCENDING)], unique=True)
user.create_index([("pet", pymongo.DESCENDING)])
user.create_index([("car", pymongo.DESCENDING)])
user.create_index([("status", pymongo.DESCENDING)])
Вот мой код:
office_id = None
car_id = None
pet_id = None
ifx_connection = IfxPy.connect(ifx_param, "", "")
stmt = IfxPy.exec_immediate(ifx_connection, sql)
dictionary = IfxPy.fetch_assoc(stmt) # Get data key / value
start = time.time()
# Loop on informix data (20 000 items)
while dictionary != False:
# Trim all string in dict
dictionary = {k: v.strip() if isinstance(v, str) else v for k,v in dictionary.items()}
# Get office
office_code = dictionary['office_code']
existing_office = office.find_one({"code": office_code})
if bool(existing_office):
office_id = existing_office['_id']
# Get pet
existing_pet = pet.find_one({"name": dictionary['pet_name']})
if bool(existing_pet):
pet_id = existing_pet['_id']
# Get car
existing_car = car.find_one({"model": dictionary['car_model']})
if bool(existing_car):
car_id = existing_car['_id']
# Get user
existing_user = user.find_one({
"username": dictionary['username'],
"car": car_id,
"pet": pet_id,
"status" : "inactive"
})
if bool(existing_user):
# Change user status
user.update_one({'_id': existing_user['_id']}, {"$set": {"status" : "active"}}, upsert=False)
# Next row
dictionary = IfxPy.fetch_assoc(stmt)
Если я удаляю код MongoDB из цикла, это займет 1,33 секунды.И если я запрашиваю MongoDB, это займет 47 секунд.У меня 20 000 предметов.Я думаю, что это действительно медленно.
Я пытался увидеть время для каждого find_one с помощью start = time.time()
, удалив все find_one и оставив только один.И если я оставлю только Office find_one, это займет ~ 12 секунд и то же самое для другого.Если я просто предоставлю клиенту find_one, это тоже займет ~ 12 секунд.Итак, ~ 12 * 4, поэтому на все find_one уходит ~ 47 секунд.
Можете ли вы сказать мне, что я делаю не так?