Search code examples
pythondjangomongodbdjango-nonrel

Embedding Vs Linking in MongoDB.when to embed and when to link?


I read this page but didn't get when to use embedding feature and when to use linking.I have a project in django for which I am using MongoDB.In my models.py file I have following models:

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)

My question is if we do embedding do we have to update the object in all models.Like if I want to update the name of a 'user' ,I would have to run update for models:Projects, Teams, Users and Tasks or linking would be better in my case?


Solution

  • First, conceptually, name your model classes as singular objects.

    Users should be User, Teams should be Team...

    Think of the model as the mold from which multiple objects will be made. User model will product Users and be stored in a table called Users where each document/row is a User object.

    Now, regarding your question, hymloth is exactly right. The way to make it a reference to a document instead of an embedded one is to change those particular fields to reference the id of a user in the user's collection. That way you are just storing an id to lookup instead of a copy of the user document. When you change the reference document, it will be changed in all of the places it is referenced as well. (Typical relational association)

    I didn't see a field for that in Django-mongoDB either but maybe you can use the traditional django ForeignKey field for this purpose. I don't know if you can mix and match so give it a shot.

    for example, your Teams class would have a field like this:

    teamLeader = ForeignKey(User)
    

    Let me know if that works.