MongoDB (Mongoose) data structure question MongoDB (Mongoose) data structure question mongoose mongoose

MongoDB (Mongoose) data structure question


Duplicating the employee info in the comments collection is really a bad idea.When an employee info needs to be changed, it will also needs to be updated in the comments.

You have a few options:

1-) Embedding the comments inside the Employee schema:

In this method we have no separate Comments collection.

If you have no need to independently query comments, this method makes sense.This way we can access a user and his/her comments in one db access and without needing any join (populate or lookup).

The schema for this can be like this:

const mongoose = require("mongoose");const employeeSchema = new mongoose.Schema({  firstName: String,  username: String,  email: String,  comments: [    new mongoose.Schema({      commentDate: Date,      comment: String    })  ]});module.exports = mongoose.model("Employee", employeeSchema);

2-) Parent referencing:

In this method we keep the reference of the comments in the Employee schema.If you don't need to access to employee from a comment, this can an option.

Employee Schema:

const mongoose = require("mongoose");const employeeSchema = new mongoose.Schema({  firstName: String,  username: String,  email: String,  comments: [    {      type: mongoose.Schema.Types.ObjectId,      ref: "Comment"    }  ]});module.exports = mongoose.model("Employee", employeeSchema);

Comment Schema:

const mongoose = require("mongoose");const commentSchema = new mongoose.Schema({  commentDate: Date,  comment: String});module.exports = mongoose.model("Comment", commentSchema);

3-) Child referencing

In this method we keep reference of the employee in the comments.So if you need to access the comments from an employee we need to use Populate Virtual feature of mongoose. Becase in employee schema we don't have a reference to the comments.

Employee Schema:

const mongoose = require("mongoose");const employeeSchema = new mongoose.Schema(  {    firstName: String,    username: String,    email: String  },  {    toJSON: { virtuals: true } // required to use populate virtual  });// Populate virtualemployeeSchema.virtual("comments", {  ref: "Comment",  foreignField: "employee",  localField: "_id"});module.exports = mongoose.model("Employee", employeeSchema);

Comment Schema:

const mongoose = require("mongoose");const commentSchema = new mongoose.Schema({  commentDate: Date,  comment: String,  employee: {    type: mongoose.Schema.Types.ObjectId,    ref: "Employee"  }});module.exports = mongoose.model("Comment", commentSchema);

4-) Both parent and child referencing:

With this method, it is possible to select comments from employee, and employee from comments. But here we have some kind of data duplication, and also when a comment is deleted, it needs to be done in both of the collections.

const mongoose = require("mongoose");const employeeSchema = new mongoose.Schema({  firstName: String,  username: String,  email: String,  comments: [    {      type: mongoose.Schema.Types.ObjectId,      ref: "Comment"    }  ]});module.exports = mongoose.model("Employee", employeeSchema);

Comment Schema:

const mongoose = require("mongoose");const commentSchema = new mongoose.Schema({  commentDate: Date,  comment: String,  employee: {    type: mongoose.Schema.Types.ObjectId,    ref: "Employee"  }});module.exports = mongoose.model("Comment", commentSchema);


Many database implement kind of no-delete collections, implementing a delete/active flag for each document.

For example, Employees collection would become :

Employees --> _id: _id --> FirstName: string --> Surname: string --> Email: string --> Active: boolean

This way, you keep track on employees data that has been deleted, and prevent documents duplication if you have database size restrictions.

PS: nowadays you can be tackled keeping user data if they ask deletion (RGPD)


EDIT: This solution with boolean may not work if Employees document is updated and you want to keep employees firstname,name,mail,etc at the time he made the Comment.