Массовая запись в MongoEngine - PullRequest
0 голосов
/ 04 октября 2019

MongoDB и PyMongo поддерживают массовую запись или вставку нескольких документов одновременно. MongoDB:

db.collection_name.insertMany()

PyMongo:

collection.insert([list_of_objects])

Но я не смог найти ничего похожего в MongoEngine для той же цели. Существует несколько подходов, но все они вставляют по одному элементу за раз. Так неужели нет ничего похожего на это? Поскольку mongoengine построен на вершине PyMongo.

Мое требование заключается в том, что у меня есть большие объемы данных для вставки за раз, но поскольку обработка каждого документа требует времени, так что мне приходится делать слепую вставку для повышения производительности. В PyMongo есть такая возможность, поэтому, если у mongoengine нет ничего похожего, можно ли использовать экземпляр pymongo для mongoengine только для этого?

1 Ответ

0 голосов
/ 05 октября 2019

Для массовой вставки у вас есть 2 варианта:

1) Pymongo

Если ваши dict отформатированы в точной форме, как ониследует сохранить, а затем использовать pymongo, вы получите гораздо лучшую производительность, поскольку сэкономите на издержках библиотеки ORM / ODM (создание экземпляров, проверка и т. д.).

Как указано в комментариях,вы можете получить доступ к pymongo.Collection, который находится за классом Model, с помощью Model._get_collection().

Дополнительное значение - это производительность, недостатком является то, что если какие-либо документы искажены (например, отсутствует поле, отсутствует значение по умолчанию, неправильный тип,дополнительное поле и т. д.), оно будет вставлено в любом случае, так как вы обходите MongoEngine. И позже у вас могут возникнуть сюрпризы при взаимодействии с данными через вашу модель.

2) MongoEngine

Если у вас есть массив экземпляров модели, вы можете сделатьмассовая вставка в MongoEngine с использованием:

Model.objects.insert(your_array)

Если вы можете построить свой объект с помощью Model(**dict).save, то это означает, что вы можете сделать

class Person(Document):
    name = StringField()
    age = IntField(default=32)

array = [{'name': 'John'}, {'name': 'Hulk', 'age': 100}]
person_instances = [Person(**data) for data in array]

Person.objects.insert(person_instances, load_bulk=False)

# Would insert the following
#[{'_id': ObjectId('...'), 'age': 32, 'name': 'John'},
# {'_id': ObjectId('...'), 'age': 100, 'name': 'Hulk'}]

Преимущество состоит в том, что он гарантируетчто формат документов, которые вы вставляете, действителен для вашей модели MongoEngine (в моем примере это означает учет значения по умолчанию age, когда его нет в тексте). Недостатком является снижение производительности.

Короче говоря, все зависит от того, является ли ваша основная потребность в производительности или вы можете жить с накладными расходами MongoEngine.

...