Пимонго: более эффективное обновление - PullRequest
4 голосов
/ 28 сентября 2010

Я пытаюсь вставить несколько больших файлов (около 4 миллионов записей) в экземпляр монго. То, что я в основном пытаюсь достичь, - это обновить существующие данные данными из файлов. Алгоритм будет выглядеть примерно так:

rowHeaders = ('orderId', 'manufacturer', 'itemWeight')
for row in dataFile:
    row = row.strip('\n').split('\t')
    row = dict(zip(rowHeaders, row))

    mongoRow = mongoCollection.find({'orderId': 12344})
    if mongoRow is not None:
        if mongoRow['itemWeight'] != row['itemWeight']:
            row['tsUpdated'] = time.time()
    else:
        row['tsUpdated'] = time.time()

    mongoCollection.update({'orderId': 12344}, row, upsert=True)

Итак, обновите всю строку, кроме «tsUpdated», если веса одинаковые, добавьте новую строку, если строка не в монго, или обновите всю строку, включая «tsUpdated» ... это алгоритм

Вопрос: можно ли сделать это быстрее, проще и эффективнее с точки зрения Монго? (в конце концов с какой-то массовой вставкой)

1 Ответ

5 голосов
/ 17 октября 2010

Объедините уникальный индекс на orderId с запросом на обновление, где вы также проверяете наличие изменений на itemWeight. Уникальный индекс предотвращает вставку только с измененной отметкой времени, если orderId уже присутствует и itemWeight совпадает.

mongoCollection.ensure_index('orderId', unique=True)
mongoCollection.update({'orderId': row['orderId'],
    'itemWeight': {'$ne': row['itemWeight']}}, row, upsert=True)

Мой тест показывает увеличение производительности в 5-10 раз по сравнению с вашим алгоритмом (в зависимости от количества вставок и обновлений).

...