Mongoose relation – Deep collections connect with populate

package.json

{
  "name": "mongorelation",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start":"nodemon app.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "mongoose": "^5.10.11",
    "nodemon": "^2.0.6"
  }
}

app.js

const mongoose = require('mongoose');
const { model, Schema } = require('mongoose');

mongoose.connect('mongodb://localhost:27017/relation',
    { useNewUrlParser: true, useFindAndModify: false, useUnifiedTopology: true })
    .then(() => { console.log(`Database successfully connected`) })
    .catch((e) => { console.log(`Database Not Connected : `, e.message) })

const app = require('express')()

const DepartmentSchema = new Schema({
    name: String,
    location: String
})

var EmployeeSchema = new Schema({
    firstName: String,
    lastName: String,
    mobile: String,
    department: {type:Schema.Types.ObjectId, ref: 'department'}
})

const CompanySchema = new Schema({
    name: String,
    address: String,
    employee: [{type: Schema.Types.ObjectId, ref: 'employee'}]
})

var Department = model("department", DepartmentSchema)
var Employee = model("employee", EmployeeSchema)
var Company = model("company", CompanySchema)

app.use("/", async (req, res) => {
    await Department.deleteMany({}) //remove
    await Department.create({ name: 'IT Department', location: 'Building A' })//.then((rs) => { console.log('Create Result : ', rs) })
    await Department.create({ name: 'Marketing Department', location: 'Building B' })//.then((rs) => { console.log('Create Result : ', rs) })

    await Employee.deleteMany({})
    await Employee.create({
        firstName: 'Viktor',
        lastName: 'Kjartansson',
        mobile: '123456',
        department: await Department.findOne({name: 'IT Department'})
    })
    await Employee.create({
        firstName: 'Mary',
        lastName: 'Holmes',
        mobile: '6789',
        department: await Department.findOne({name: 'Marketing Department'})
    })

    await Company.deleteMany({})
    await Company.create({name: 'InfoCare', address:'addr1', employee: await Employee.find({})})
    res.json({
        depatments: await Department.find({}),
        employees: await Employee.find({}),
        //employeesWithDep: await Employee.find().populate('department')
        //employeesWithDep: await Employee.find().populate('department', 'name'),
        //company: await Company.find({})
        //companyWithEmp: await Company.find({}).populate('employee')
        companyWithEmpAndDept: await Company.find({})
        .populate({
            path: 'employee', 
            model:'employee',
            populate: {
                path: 'department',
                model: 'department'
            }
        })        
    })
})


app.listen(3050, () => { console.log(`Server Connected: http://localhost:3050`) })

Subdocs.js

We can use SubDocs to nest data in mongoose

comments: [CommentSchema] - Instance from comments collection inside of Posts
//We can use SubDocs to nest data in mongoose
//comments: [CommentSchema] - Instance from comments collection inside of Posts
const mongoose = require('mongoose');
const { model, Schema } = require('mongoose');

mongoose.connect('mongodb://localhost:27017/relation',
    { useNewUrlParser: true, useFindAndModify: false, useUnifiedTopology: true })
    .then(() => { console.log(`Database successfully connected`) })
    .catch((e) => { console.log(`Database Not Connected : `, e.message) })

const app = require('express')()

const CommentSchema = new Schema({
    text: String,
    userName: String
})
const CommentModel = model("comment", CommentSchema)

const PostSchema = new Schema({
    text: String,
    userName: String,
    comments: [CommentSchema]  
})
const PostModel = model("post", PostSchema)

app.use("/", async (req, res) => {
    //Clear Collections
    await PostModel.deleteMany({}) //remove
    await CommentModel.deleteMany({}) //remove

    let aComment = new CommentModel({text: "First Comment", userName: "Arun" })
    //const resultc = await aComment.save()

    let aPost = new PostModel({ text: 'Hi There', userName: 'Arun' })
    aPost.comments.push(aComment)
    const resultp = await aPost.save()
    
    res.json({
        post: resultp,
        message: "Success"
    })
})


app.listen(3050, () => { console.log(`Server Connected: http://localhost:3050`) })


/*OUTPUT
{
    "post": {
        "_id": "5f9a5fea91fa211a90dfa92d",
        "text": "Hi There",
        "userName": "Arun",
        "comments": [
            {
                "_id": "5f9a5fea91fa211a90dfa92c",
                "text": "First Comment",
                "userName": "Arun"
            }
        ],
        "__v": 0
    },
    "message": "Success"
}
*/

separate.js

Comments in separate collection and just to make the association by ID – it is called Population.

comments: [{type: Schema.Types.ObjectId, ref: 'comment'}]
//Comments in separate collection and just to make the association by ID - it is called Population
const mongoose = require('mongoose');
const { model, Schema } = require('mongoose');

mongoose.connect('mongodb://localhost:27017/relation',
    { useNewUrlParser: true, useFindAndModify: false, useUnifiedTopology: true })
    .then(() => { console.log(`Database successfully connected`) })
    .catch((e) => { console.log(`Database Not Connected : `, e.message) })

const app = require('express')()

const CommentSchema = new Schema({
    text: String,
    userName: String
})
const CommentModel = model("comment", CommentSchema)

const PostSchema = new Schema({
    text: String,
    userName: String,
    comments: [{ type: Schema.Types.ObjectId, ref: 'comment' }]
})
const PostModel = model("post", PostSchema)

app.use("/", async (req, res) => {
    //Clear Collections
    await PostModel.deleteMany({}) //remove
    await CommentModel.deleteMany({}) //remove

    let aComment = new CommentModel({ text: "First Comment", userName: "Arun2" })
    await aComment.save()

    let aPost = new PostModel({ text: 'Hi There', userName: 'Arun2' })
    aPost.comments.push(aComment);
	await aPost.save()

    let result = await PostModel.find({})
        .populate('comments') //postschema key properties
        // .exec((err, comment) => {
        //     console.log("comment : " , comment)
        //     return result
        // })
    //console.log("result : ", result)

    res.json({
        post: result,
        message: "Success"
    })
})


app.listen(3050, () => { console.log(`Server Connected: http://localhost:3050`) })

/* OUTPUT

--comments
{
    "_id" : ObjectId("5f9a7c04624ecd261c559c93"),
    "text" : "First Comment",
    "userName" : "Arun2",
    "__v" : 0
}

--posts
{
    "post": [
        {
            "comments": [
                {
                    "_id": "5f9a7c04624ecd261c559c93",
                    "text": "First Comment",
                    "userName": "Arun2",
                    "__v": 0
                }
            ],
            "_id": "5f9a7c04624ecd261c559c94",
            "text": "Hi There",
            "userName": "Arun2",
            "__v": 0
        }
    ],
    "message": "Success"
}

*/



Reference

Mongoose Subdocs and Population
ESP8266 mini sends SMS when door opens
Mongoose – deep collections connect with populate

Leave a Reply

Your email address will not be published. Required fields are marked *