Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoengine bulk update without objects.update()

I'd like to bulk update changes in mongoengine Documents' instances, but as far as I understood, model.objects.update(...) makes the same update in all documents that match the criteria.

Example:

entities = Foo.objects

result = entities.update(
    set__foo='new bar',
    upsert=True,
    full_result=True)

That sets the property foo to new bar on all documents that have their foo equals to bar. I would like to make different changes on each document.

Is this possible? Something like this:

entities = Foo.objects

...  # make changes to each entity in entities

entities = Foo.objects.update(entities)
# these entities were bulk updated in mongodb.
like image 362
ldavid Avatar asked Jun 19 '15 16:06

ldavid


1 Answers

Just coming back here, in case someone run into this: mongoengine doesn't really give us any way to bulk different updates for many records, but pymongo does! With it, I could easily write a update:

from pymongo import UpdateOne
from mongoengine import Document, ValidationError

class Foo(Document):
    ...

bulk_operations = []

for entity in entities:
    try:
        entity.validate()  
        bulk_operations.append(
            UpdateOne({'_id': entity.id}, {'$set': entity.to_mongo().to_dict()}))

    except ValidationError:
        pass

if bulk_operations:
    collection = Foo._get_collection() \
        .bulk_write(bulk_operations, ordered=False)

Here, I get Foo's collection with _get_collection() and execute the list of UpdateOne operations - updates, as they were constructed.

like image 115
ldavid Avatar answered Nov 05 '22 08:11

ldavid