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

2

5

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?

Shalne answered 23/11, 2011 at 9:29 Comment(0)
A
3

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.

Allegro answered 23/11, 2011 at 17:30 Comment(0)
M
4

In your example, yes, changing the name of a user implies that if you use embedding then you must update all other documents with an extra step. What is more appropriate in your situation is linking (referencing). This involves an extra step at query time, but because of your particular "business logic", it is better.

Generally, if a given document needs to be accessed from a number of different places then it makes sense to make it a reference rather than embedded. The same applies in situations when a document changes frequently.

Materfamilias answered 23/11, 2011 at 9:51 Comment(3)
Just replace all your EmbeddedModelField('Users') with a ReferenceField('Users').Materfamilias
But I am using Django-mongoDB engine and it has no field like ReferenceField. :(Shalne
Well, I didn't know that. Why not switch to mongoengine, which is more mature?Materfamilias
A
3

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.

Allegro answered 23/11, 2011 at 17:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.