一个mongoengine.DynamicEmbeddedDocument可以用来利用MongoDB的灵活架构设计少.它是可扩展的,不会对字段应用类型约束,afaik.
一个mongoengine.DictField同样允许使用MongoDB的无模式性质.在文档中他们只是说(wrt DictField
)
这类似于嵌入式文档,但结构未定义.
这是否意味着,届时,mongoengine.fields.DictField
和mongoengine.DynamicEmbeddedDocument
是完全可以互换?
编辑(更多信息):
mongoengine.DynamicEmbeddedDocument
从mongoengine.EmbeddedDocument
代码继承而来的是:
A
mongoengine.Document
不存储在自己的集合中.mongoengine.EmbeddedDocuments
应该mongoengine.Documents
通过mongoengine.EmbeddedDocumentField
字段类型用作字段.
A mongoengine.fields.EmbeddedDocumentField
是
嵌入的文档字段 - 具有声明的document_type.只有有效值是子类
EmbeddedDocument
.
这是否意味着唯一使得DictField
并且DynamicEmbeddedDocument
不完全可互换的是DynamicEmbeddedDocument
必须通过EmbeddedDocumentField
字段类型定义?
从我所看到的,两者是相似的,但不完全可以互换.根据您的需求,每种方法都可能略有优势.首先,正如您所指出的,这两种方法在文档中需要不同的定义,如下所示.
class ExampleDynamicEmbeddedDoc(DynamicEmbeddedDocument): pass class ExampleDoc(Document): dict_approach = DictField() dynamic_doc_approach = EmbeddedDocumentField(ExampleDynamicEmbeddedDoc, default = ExampleDynamicEmbeddedDoc())
注意:默认值不是必需的,但需要将dynamic_doc_approach字段设置为ExampleDynamicEmbeddedDoc对象才能保存.(即在设置example_doc_instance.dynamic_doc_approach = {}后尝试保存会抛出异常).此外,如果您不想将字段绑定到特定类型的EmbeddedDocument,则可以使用GenericEmbeddedDocumentField,但该字段仍然需要指向从EmbeddedDocument子类化的对象才能保存.
设置完成后,两者在功能上类似,因为您可以根据需要将数据保存到它们,并且没有任何限制:
e = ExampleDoc() e.dict_approach["test"] = 10 e.dynamic_doc_approach.test = 10
但是,我看到的一个主要区别是,您可以查询添加到DictField的任何值,而不能使用DynamicEmbeddedDoc.
ExampleDoc.objects(dict_approach__test = 10) # Returns a QuerySet containing our entry. ExampleDoc.objects(dynamic_doc_approach__test = 10) # Throws an exception.
话虽这么说,使用EmbeddedDocument具有验证您知道将在文档中出现的字段的优势.(我们只需要将它们添加到ExampleDynamicEmbeddedDoc定义中).因此,我认为最好在您熟悉字段的架构时使用DynamicEmbeddedDocument,并且只预期最少添加字段(您不需要查询).但是,如果您不关心验证或预计会添加许多您要查询的字段,请使用DictField.