Mongoengine-仅保存一个嵌入式文档

问题描述

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

因此,这段代码使我只能在paragraphs文档中保存Contract字段,这比保存整个文档要有效得多。但是,这仍然需要一段时间,因为文档中有很多段落。

我将属性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对象就可以更新特定的段落。

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

顺便说一句,如果这是您唯一的对象,我什至建议您使用SQL数据库,它似乎更适合您的需求。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...