问题描述
我有一个很大的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数据库,它似乎更适合您的需求。