【问题标题】:Mongoengine - save only one embedded documentMongoengine - 只保存一个嵌入文档
【发布时间】:2020-08-31 19:09:02
【问题描述】:

我有一个非常大的 MongoDB 文档,因此需要几秒钟来保存。其中一个字段是嵌入文档的列表。当我更新列表中的一项并希望保存到数据库时,我希望能够只保存特定的嵌入文档而不是整个文档。

我的代码的一个缩写部分如下:

class Paragraph(mongoengine.EmbeddedDocument):
    _id = mongoengine.ObjectIdField(required=True, default=lambda: ObjectId())
    text = mongoengine.StringField()
    updated = mongoengine.BooleanField()

class Contract(mongoengine.Document):
    paragraphs = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Paragraph))

    def save(self, **kwargs):
        if kwargs.get('update_only', False):
            super(Contract, self).update(set__paragraphs=self.paragraphs)
        else:
            super(Contract, self).save(**kwargs)

所以这段代码允许我只保存Contract 文档中的paragraphs 字段,这已经比保存整个文档高效多了。但是,这仍然需要一段时间,因为文档中有很多段落。

我将属性updated 添加到Paragraph。我希望能够只保存那些标记为已更新的段落。

我找到了一种方法,首先从数据库中删除所有更新的段落,然后添加新的段落。

Contract.objects(id=id).update_one(pull__paragraphs={'_id': id_of_updated_paragraph})
Contract.objects(id=id).update_one(add_to_set__paragraphs=updated_paragraph)

这仍然感觉非常低效。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: python-3.x mongodb mongoengine


    【解决方案1】:

    好吧,我知道 mongodb 不习惯用作关系数据库,但它可以,而且有时是需要的。

    似乎这是其中之一。 让我解释一下为什么。 尽管在您的示例中,所有段落仅在特定合同中重要,但您修改段落对象的频率高于修改合同对象。

    将每个段落分解成自己的文档将为您提供您正在寻找的动态行为,您将能够更新特定段落而无需接触 Contract 对象。

    您还可以删除段落,只需更改 Contract 对象即可轻松更改其顺序。

    顺便说一句,如果这是你唯一的对象,我什至建议你转移到 SQL 数据库,它似乎更适合你的需要。

    【讨论】:

    • 我认为这是有道理的。离开非关系数据库的逻辑是一种耻辱,但如果没有其他方法可以只保存对象的一部分,那么将段落设为引用列表而不是嵌入文档可能是可行的方法。
    猜你喜欢
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    相关资源
    最近更新 更多