Mongoengine - 只保存一个嵌入文档

Mongoengine - save only one embedded document

我有一个 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)

这仍然感觉效率很低。有更好的方法吗?

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

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

将每个段落分解成自己的文档将为您提供您正在寻找的动态行为,您将能够在不触及合同对象的情况下更新特定段落。

您还可以删除段落,并且只需更改 Contract 对象即可轻松更改它们的顺序。

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