Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meteor: Embed documents inside a document or separate them into each collection object and link them?

I am running into a scenario where I am asking myself do I need to put each entity (a Classroom has many students) into separate Meteor.collection object or rather embed an array of students inside the classroom object and have one Meteor.collection Classroom object.

My instinct tells me to put Classroom and Students in their own Meteor.collections but I am not sure how to establish a one to many relationship between the two Meteor collection objects.

What if there are many more traditional one-to-many, many-to-many relationships translate into Meteor way of doing things?

My question arises from the fact that .aggregate() is not supported, and realizing that it's impossible without doing a recursive loop to grab nested and embedded documents, inside a parent document in which Meteor collection exists (ex. Classroom).

like image 686
KJW Avatar asked Jul 29 '13 23:07

KJW


People also ask

What is Meteor collection?

Collections are Meteor's way of storing persistent data. The special thing about collections in Meteor is that they can be accessed from both the server and the client, making it easy to write view logic without having to write a lot of server code.

How do I embed a document in MongoDB?

As we know that in the mongo shell, documents are represented using curly braces ( {} ) and inside these curly braces we have field-value pairs. Now inside these fields, we can embed another document using curly braces {} and this document may contain field-value pairs or another sub-document.

What is an embedded document?

An embedded document is when one document (often a structured text file, or a binary, or anything else) is embedded within another. (This discussion assumes that the result is a linear sequence of bytes/characters--use of more advanced filing systems is beyond the scope of this discussion).

When should we embed one document with another in MongoDB?

An embedded, or nested, MongoDB Document is a normal document that's nested inside another document within a MongoDB collection. Embedded documents are particularly useful when a one-to-many relationship exists between documents.


2 Answers

Most of the time it is useful to put separate object types into separate collections.

Let's say we have a one to many relationship:

Classrooms.insert({
  _id: "sdf8ad8asdj2jef",
  name: "test classroom"
});

Students.insert({
  _id: "lof8gzanasd9a7j2n",
  name: "John"
  classroomId: "sdf8ad8asdj2jef"
});


Get all Students in classroom sdf8ad8asdj2jef:

Students.find({classroomId: "sdf8ad8asdj2jef"});

Get the classroom with student lof8gzanasd9a7j2n:

var student = Studtents.findOne("lof8gzanasd9a7j2n");
var classroom = Classrooms.find(student.classroomId);


Putting the objects into separate collections is especially useful when you are going to use Meteor.publish() and Meteor.subscribe(). Meteor.publish() is pretty handy when you want to publish only data to the client that is really relevant to the user.

The following publishes only students who are in the room with the given classroomId. (So the client doesn't have to download all student objects from the server database. Only those who are relevant.)

Meteor.publish("students", function (classroomId) {
  return Students.find({classroomId: classroomId});
});


Many to many relationships are also not that complicated:

Classrooms.insert({
  _id: "sdf8ad8asdj2jef",
  name: "test classroom"
  studentIds: ["lof8gzanasd9a7j2n"]
});

Students.insert({
  _id: "lof8gzanasd9a7j2n",
  name: "John"
  classroomIds: ["sdf8ad8asdj2jef"]
});


Get all students in classroom sdf8ad8asdj2jef:

Students.find({classroomIds: "sdf8ad8asdj2jef"});

Get all classrooms with student lof8gzanasd9a7j2n:

Classrooms.find({studentIds: "lof8gzanasd9a7j2n"});


More information on MongoDBs read operations.

like image 118
Tim Bartsch Avatar answered Sep 21 '22 10:09

Tim Bartsch


Separate collections for students and classrooms seems more straightforward.

I think just keeping a 'classroom' or 'classroomId' field in each student document will allow you to join the two collections when necessary.

like image 27
user728291 Avatar answered Sep 20 '22 10:09

user728291