使用新对象更新记录



假设我有以下MongoDB集合(在本例中使用mongomock,因此很容易复制(:

import mongomock
collection = mongomock.MongoClient().db.collection
objects = [{'name': 'Alice', 'age': 21}, {'name': 'Bob', 'age': 20}]
collection.insert_many(objects)

然后我想用一些新对象的字段更新我现有的对象:

new_objects = [{'name': 'Alice', 'height': 170}, {'name': 'Caroline', 'height': 160}]

我唯一能想到的方法是:

for record in new_objects:
if collection.find_one({'name': record['name']}) is not None:
collection.update_one({'name': record['name']}, {'$set': {'height': record['height']}})
else:
collection.insert_one(record)

然而,如果new_objects非常大,那么这种方法就会变得很慢——有没有办法使用update_many

您不能使用update_many(),因为它需要一个单独的过滤器,而在您的用例中,由于每个过滤器都不同,所以无法工作。

一个更简单的构造使用upsert=True来避免插入/更新逻辑,并设置记录中指定的所有字段,这是较少编码的:

for record in objects + new_objects:
collection.update_one({'name': record.get('name')}, {'$set': record}, upsert=True)

如果随着更新数量的增加,速度变慢了,请确保在name字段上有一个索引,使用(在mongoshell中(:

db.collection.createIndex( { "name": 1 } )

您可以通过使用bulk_write操作来压缩更多的性能。示例:

from pymongo import MongoClient, UpdateOne
collection = MongoClient().db.collection
objects = [{'name': 'Alice', 'age': 21}, {'name': 'Bob', 'age': 20}]
new_objects = [{'name': 'Alice', 'height': 170}, {'name': 'Caroline', 'height': 160}]
updates = []
for record in objects + new_objects:
updates.append(UpdateOne({'name': record.get('name')}, {'$set': record}, upsert=True))
collection.bulk_write(updates)
for record in collection.find({}, {'_id': 0}):
print(record)

提供:

{'name': 'Alice', 'age': 21, 'height': 170}
{'name': 'Bob', 'age': 20}
{'name': 'Caroline', 'height': 160}

相关内容

  • 没有找到相关文章

最新更新