如何在pymongo中执行一次多个更新查询?

时间:2016-07-28 13:13:53

标签: python mongodb pymongo

我需要执行超过100000个更新查询,db.collection_name.update(upsert=True)只能执行一个查询语句,如果我逐个执行所有查询,则速度太慢。

有没有办法将多个查询收集到列表中,然后在pymongo中执行一次?

我尝试使用bulk,它不会保存任何时间,也不会保存事务操作:(

这是我的代码段:

bulk = self._db.initialize_unordered_bulk_op()
for user_id, result in results.items():
    time_stamp = time.strftime('%Y-%m-%d:%H:%M:%S')
    history = {
        'create_at': time_stamp,
        'results': result
    }
    bulk.find({'user_id': user_id}).update(
        {'$set': {'update_at': time_stamp}}
    )
    bulk.find({'user_id': user_id}).update(
        {'$addToSet': {'history': history}}
    )
bulk.execute()

它与以下更新语句的速度几乎相同:

self._db.update(
    {'user_id': user_id},
    {'$set': {'update_at':time.strftime('%Y-%m-%d:%H:%M:%S')}}, 
    upsert=True
)
self._db.update(
    {'user_id': user_id},
    {'$addToSet': {'history': history}},
    upsert=True
)

1 个答案:

答案 0 :(得分:0)

您可以引入一个计数器变量,以确保批量发送更新,因为写入命令可以接受不超过1000次操作,因此需要将操作分组以进行最多1000次操作并重新执行批量操作当循环达到1000次迭代时。此外,DRY(不要重复自己):将更新语句$set$addToSet合并到一个更新文档中。您的最终更新脚本应该会更好:

bulk = self._db.initialize_unordered_bulk_op()
counter = 0;

for user_id, result in results.items():
    time_stamp = time.strftime('%Y-%m-%d:%H:%M:%S')
    history = {
        'create_at': time_stamp,
        'results': result
    }
    bulk.find({'user_id': user_id}).update({
        '$set': { 'update_at': time_stamp },
        '$addToSet': { 'history': history }
    })
    counter++

    if (counter % 1000 == 0):
        bulk.execute()
        bulk = self._db.initialize_unordered_bulk_op()

if (counter % 1000 != 0):
    bulk.execute()