Collection need to have ids from 2 other different collections in same database

I am creating my first project using MongoDB. Where there is a need of having two foreign keys in a collection if I explain in terms of SQL. Is there anyone who can help me with this. I am unable to make up the schemas of the collection its getting complicated. I would be so much grateful if you could help me with this. Connect or ping me on Linkedin

Hi @Himal_Gautam ,

We can help you design your schema. But can you share more information as of what kind of data and what are the relationships between those data objects you need to use.

In mongoDB foreign keys can be described in many ways depanding on the relationship type and required access patterns.

Please read the following article to get started:

Thanks

Pavel

I have given the basic requirements below on basis of which I have to develop schema.

I have also developed schema according to my basic knowledge. Currently doing courses from MongoDB Schema. So pardon for silly mistakes.

Attachment:- Image of visual schema made using moon modeler.
*blue:- collection
*green:-sub-documents inside the collection

1 BASIC REQUIREMENTS
 The end-users for the system are
=>Teacher => Student =>Admin
 The user will log in using a username & password.
 Username & password are predefined (password can be updated after the first login by user)
 After Login The first page should be the dashboard showing their details.
 Must be a page providing important links related to fees, student portal, etc.
 Website UI should be attractive and responsive to fit all the devices.
 The navbar should be horizontal. If possible add visual effects.

2 TEACHER REQUIREMENTS
 The teacher must be able to update notices & internal marks.
 Must be able to give assignments to students.
 Must be able to generate reports such as attendance reports, assignments reports, and results.
 Reports must be of the specific teacher where he must be able to sort & filter on based on the subject, student, etc.
 Teachers can teach multiple subjects but subjects can only be taught by one teacher.

3 STUDENT REQUIREMENTS
 Students must be able to see the notices and assignments provided by the faculty.
 Must be able to submit assignments and attendance.
 Must be able to see his/her assignment and attendance report where he/she will be able to sort and filter on basis of subject, etc.
 Must get results on basis of the semester.
 Students can study multiple subjects, as well as a subject, can be studied by multiple students.

4 ADMIN REQUIREMENTS
 The admin must be able to update & delete most of the data.
 Must be able to generate reports from every datastore.
 Must be able to sort and filter the data according to his/her choice.
 Must be able to generate profile reports of specific persons on basis of his/her ID.
 Profile report must have all the data from all datastore on basis of the ID.

ATTACHMENT:-

Hi @Himal_Gautam ,

The requirements sounds like a perfect candidate to use realm application services for web or cross-platform applications (react-native etc…)

This will allow you the following main advantages:

  • application user management including username/password authentication , but can also allow you to easily integrate authentication like Google or Facebook, Apple etc…
  • You can define roles per collection/data type where each document can be evaluated.
  • You will get robust sdks to develop different applications for web/mobile using the same backend.
  • Using Atlas cloud database with all of its great features : Triggers and Atlas text search

Now your schema is very relational oriented and you should think in a different approach when it comes to MongoDB, lets check the provided requirements and see if we can create a better mongoDB schema.

So admins, teachers, students are basically users that need to gain a specific profile. Once this profile is obtained they will get different ability to perform different queries on the collective data. All the related UI effects is off scope for data modeling, as we need to focus what data is needed and how it is accessed.

So I thought about 5 main collections

Users

{ _id: ObjectId("621f414cbc55523f3f1f6922"),
  userName: 'Teacher1',
  email: 'Teacher1@example.com',
  profile: [ 'Teacher' ] }
{ _id: ObjectId("621f43b5bc55523f3f1f6925"),
  userName: 'Student1',
  email: 'Student1@example.com',
  profile: [ 'Student' ] }
{ _id: ObjectId("621f43ccbc55523f3f1f6926"),
  userName: 'Teacher2',
  email: 'Teacher2@example.com',
  profile: [ 'Teacher', 'Admin' ] }

So in here every user is classified with a profile, of course you can add the attributes that each user needs. Once the profile is obtained the Data Access Layer allows it to operate on diffrerent levels of data as you mentioned.

It makes sense to index , userName or profile if you want data of specific users or all “admins”.

Subjects

{ _id: ObjectId("621f4e28bc55523f3f1f693f"),
  subjectName: 'Math',
  subjectCode: 'ABC',
  prerequisties: [ { subjectName: 'Basic Math', code: 'XYZ' } ] }

So each subject has its own data which mostly referential with for example prerequisites.

Classes or Lessons

{ _id: ObjectId("621f442bbc55523f3f1f6929"),
  teacher: { teacherId: ObjectId("621f414cbc55523f3f1f6922"),
                 teacherName :  "Teacher1" },
  semesterStart: 2021-12-31T22:00:00.000Z,
  semesterEnd: 2022-04-29T21:00:00.000Z,
  schedule: { interval: 'weekly', scheluledDays: [ 'Monday' ] },
  totalScheduledClasses: 25,
  subject: 
   { subjectId: ObjectId("621f4462bc55523f3f1f692b"),
     subjectName: 'Math',
     code: 'ABC' },
  attendees: 
   [ { studentId: ObjectId("621f43b5bc55523f3f1f6925"),
       numberAttendence: 0 },
     { studentId: ObjectId("621f464fbc55523f3f1f692f"),
       numberAttendence: 1 } ] ,
totalAttendees :  2}

Here every classes gets the teacherId, and his name and can be indexed with unique index on teacher.teacherId as well as on semsterStart : 1, semsterEnd : 1. I think that each class is schedule for a semster probably so it make sense to have a document per class per semster and figure out how to represent it by using the “scehdule” object. For example a weekly calss on Monday etc. The totalScheduledClasses is calculated by the amount of possible classes. Now every attendee is pushed into a class with its Id and the number of times he’s been in a class, every time he submits for going it increases this value. Now you could report on percentage of each attendee and the classes.

Here every query can be to find a class for attendee as attendees.studentId can be indexed and each student can fetch all the relevant information for him. What information you show on the application is up to the code/projection of the query for student role. Teacher role will probably pass a different projection or maybe aggregation to see its own data.

Assignments

{ _id: ObjectId("621f46b3bc55523f3f1f6932"),
  classId: ObjectId("621f442bbc55523f3f1f6929"),
  teacher: { teacherId: ObjectId("621f414cbc55523f3f1f6922"),
                 teacherName :  "Teacher1" },
  assignement: 
   { numberOfQuestions: 5,
     questions: [ { Title: 'What is X?', Body: 'Please explain', points: 15 } ] },
  assigness: 
   [ ObjectId("621f43b5bc55523f3f1f6925"),
     ObjectId("621f486bbc55523f3f1f6936") ],
  subject: { subject: 'Math', code: 'ABC' } }

Each assignment is populated into the assignments document where the relevant class, teacher, subject, assignees list and the assignment itself can be saved.

Same model can work for notices if you add a type field to distinguish and change the fields to be more notice related. Usually we will probably by default start with a specific student or copy the attendees of a class for notice and then will allow the user/teacher to remove/add relevant users from users collection.

AssignmentSubmissions

{ _id: ObjectId("621f4cc7bc55523f3f1f6939"),
  classId: ObjectId("621f4cf2bc55523f3f1f693a"),
   teacher: { teacherId: ObjectId("621f414cbc55523f3f1f6922"),
                 teacherName :  "Teacher1" },
  studentIds: [ ObjectId("621f4d30bc55523f3f1f693c") ],
  result: { mark: 90, extra: 'Good but not the best.' },
  subject: { subjectName: 'Math', code: 'ABC' } }

Whenever a student or group of students submit a assignment for review/mark it create a document where the relevant data is saved per submission. Now here we can again index class, teacher or the assignments studentIds or the subject.subjectName to get specific results for reports.

Let me know if the model make sense to you. If you see any foreseen issues lets discuss…

Thanks
Pavel