【问题标题】:Mongoengine bulk update without objects.update()没有objects.update()的Mongoengine批量更新
【发布时间】:2015-09-05 17:28:15
【问题描述】:

我想批量更新 mongoengine 文档实例中的更改,但据我了解,model.objects.update(...) 在所有符合条件的文档中进行相同的更新

例子:

entities = Foo.objects

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

这会将所有foo 等于bar 的文档的属性foo 设置为new bar。我想对每个文档进行不同的更改

这可能吗?像这样的:

entities = Foo.objects

...  # make changes to each entity in entities

entities = Foo.objects.update(entities)
# these entities were bulk updated in mongodb.

【问题讨论】:

    标签: python pymongo mongoengine


    【解决方案1】:

    回到这里,以防有人遇到这种情况:mongoengine 并没有真正给我们任何方法来批量更新许多记录,但 pymongo 可以!有了它,我可以轻松编写更新:

    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)
    

    在这里,我使用 _get_collection() 获取 Foo 的集合并执行 UpdateOne 操作列表 - 更新,因为它们是构造的。

    【讨论】:

    • 我必须将 entity.id 转换为字符串才能正常工作,即 str(entity.id)
    • 仍然是我找到的解决此问题的最佳解决方案!在我的情况下,我必须过滤另一个字段,因为我的 UpdateOne 必须具有 upsert=True
    猜你喜欢
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    相关资源
    最近更新 更多