在MongoDB中嵌入Vs链接。何时嵌入和何时链接?

时间:2011-11-23 09:29:26

标签: python django mongodb django-nonrel

我读了this page但是没有得到何时使用嵌入功能以及何时使用链接。我在django中有一个项目,我正在使用MongoDB。在我的models.py文件中,我有以下模型:

class Projects(models.Model):
    projectName =models.CharField(max_length = 100,unique=True,db_index=True)
    projectManager = EmbeddedModelField('Users')

class Teams(models.Model):
    teamType = models.CharField(max_length =100)
    teamLeader = EmbeddedModelField('Users')
    teamProject = EmbeddedModelField('Projects')
    objects = MongoDBManager()

class Users(models.Model):
    name = models.CharField(max_length = 100,unique=True)
    designation = models.CharField(max_length =100 )
    teams = ListField(EmbeddedModelField('Teams'))



class Tasks(models.Model):
    title = models.CharField(max_length = 150)
    description = models.CharField(max_length=1000)
    priority = models.CharField(max_length=20)
    Status = models.CharField(max_length=20)
    assigned_to = EmbeddedModelField('Users')
    assigned_by = EmbeddedModelField('Users')
    child_tasks = ListField()
    parent_task = models.CharField(max_length = 150)

我的问题是,如果我们进行嵌入,我们是否必须更新所有模型中的对象。如果我想更新“用户”的名称,我将不得不为模型运行更新:项目,团队,用户和在我的情况下,任务或链接会更好吗?

2 个答案:

答案 0 :(得分:4)

在您的示例中,是的,更改用户名称意味着如果您使用嵌入,则必须使用额外步骤更新所有其他文档。在您的情况下更合适的是链接(引用)。这涉及到查询时的额外步骤,但由于您的特定“业务逻辑”,它更好。

通常,如果需要从许多不同的地方访问给定的文档,那么将其作为引用而不是嵌入是有意义的。这同样适用于文档频繁更改的情况。

答案 1 :(得分:3)

首先,从概念上讲,将模型类命名为单个对象。

用户应该是用户,团队应该是团队......

将模型视为将从中制作多个对象的模具。用户模型将产品用户并存储在名为Users的表中,其中每个文档/行都是User对象。

现在,关于你的问题,hymloth是完全正确的。使其成为对文档而不是嵌入文档的引用的方法是更改​​这些特定字段以引用用户集合中的用户的id。这样,您只需将id存储到查找而不是用户文档的副本。更改参考文档时,它将在引用的所有位置更改。 (典型的关系协会)

我没有在Django-mongoDB中看到一个字段,但也许你可以使用传统的django ForeignKey字段来达到这个目的。我不知道你是否可以混搭,所以试一试。

例如,你的Teams类将有一个这样的字段:

teamLeader = ForeignKey(User)

如果有效,请告诉我。