【问题标题】:What is the difference between EmbeddedDocumentField and ReferenceField in mongoenginemongoengine 中的 EmbeddedDocumentField 和 ReferenceField 有什么区别
【发布时间】:2013-07-01 12:17:42
【问题描述】:

在内部,这两个字段有什么区别?这些字段在 mongo 中映射到什么样的模式?另外,应该如何将具有关系的文档添加到这些字段中?例如,如果我使用

from mongoengine import *

class User(Document):
    name = StringField()

class Comment(EmbeddedDocument):
    text = StringField()
    tag  = StringField()

class Post(Document):
    title    = StringField()
    author   = ReferenceField(User)
    comments = ListField(EmbeddedDocumentField(Comment)) 

然后打电话

>>> some_author = User.objects.get(name="ExampleUserName")
>>> post = Post.objects.get(author=some_author)
>>> post.comments
[]
>>> comment = Comment(text="cool post", tag="django")
>>> comment.save()
>>> 

我应该使用 post.cmets.append(comment) 还是 post.cmets += comment 来附加此文档?我最初的问题源于我应该如何处理这个问题。

【问题讨论】:

    标签: json dictionary schema mongoengine bson


    【解决方案1】:

    EmbeddedDocumentField 只是像DictField 这样的父文档的路径,并与mongo中的父文档存储在一条记录中。

    要保存EmbeddedDocument,只需保存父文档。

    >>> some_author = User.objects.get(name="ExampleUserName")
    >>> post = Post.objects.get(author=some_author)
    >>> post.comments
    []
    >>> comment = Comment(text="cool post", tag="django")
    >>> post.comment.append(comment)
    >>> post.save()
    
    >>> post.comment
    [<Comment object __unicode__>]
    
    >>> Post.objects.get(author=some_author).comment
    [<Comment object __unicode__>]
    

    请参阅文档:http://docs.mongoengine.org/guide/defining-documents.html#embedded-documents

    【讨论】:

    • 我想知道您是否可以更深入地了解这两种字段类型之间的区别,以及您为每种类型推荐的使用案例。我不想重复这个问题,所以我希望您可以向您的问题添加更多信息。
    • ReferenceField 是对另一个文档的引用,EmbeddedDocumentField 是一个文档的一部分。所以 ManyToMany 和 ManyToOne 关系更多地应用于不同的文档,OneToOne 关系更多地应用于一个文档。
    • 因此对于 M:M 和 M:1,您将使用 EmbeddedDocumentField,对于 1:1,您将使用 ReferenceField。我说对了吗?
    • 不,使用应该完全取决于您的要求。对于M:M 可能更好地使用参考列表,例如User 与另一个Users 的友谊。对于M:1 参考,例如User 和他的Posts,或嵌入列表,例如PostPost Tags。对于1:1 参考,例如UserUser Activity Page,或嵌入的,例如UserUser Address。但是这个例子在某些特殊情况下可能不是很好,所以我再次告诉它,如果你自己没有看到更好的例子,只需使用其中一个并在将来决定选择错误时进行重构。
    • 甜蜜!很好的解释大师欧比旺Tbicr
    【解决方案2】:

    这只是一个我们可以使用嵌入式文档的示例。

    例如,假设您将创建一个应用程序,该应用程序在需求进入时将其接收并将它们保存在数据库中。 现在您的要求是在对需求进行一些处理后,在稍后阶段将这个需求分配给一群人。

    您还需要跟踪更改并记录与根据要求进行的处理有关的活动。

    我知道我知道你可能会说我们可以使用 rdbms 与引用字段的关系。但它涉及删除任一集合中的过时记录,这只不过是在父文档被删除的情况下处理子集合维护的额外代码。(还有其他额外的努力也到位..)

    嵌入的文档被存储为父文档的一部分。维护父级也将涉及嵌入式文档。

    使用嵌入式文档创建复杂的 json 结构化数据将很容易,而不是使用用户逻辑将数据操作和处理成复杂的结构。

    现在,这里的关系是许多处理程序的一项要求(只不过是处理程序针对一项要求的活动日志)。

    【讨论】:

      猜你喜欢
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多