Mongoose Populate

What is Mongoose?

Mongoose is the most popular MongoDB database modeling framework for NodeJS.

Since MongoDB is schemeless (does not have predefined structure), Mongoose allows to had some structure to all the MongoDB collections.

Where is some example:

import * as mongoose from 'mongoose'

const Animal = new mongoose.Schema('Animal', {
  name: {
    type: String,
    required: true
  },
  color: {
    type: String
  }
}, {
  timestamp: true
})

const cat = new Animal({
  name: 'Cat',
  color: 'pink'
})

cat
  .save()
  .then(doc => {
    console.log('We have a cat', doc)
  })
  .catch(err => {
    console.warn(err.message)
  })

So our doc will be the MongoDB document with our cat information:

{
  "_id": ObjectId("5ae9b46ea22f8b4e049e1e5a"),
  "name": "Cat",
  "color": "pink",
  "createdAt" : ISODate("2018-06-07T16:51:36.023Z"),
  "updatedAt" : ISODate("2018-06-07T16:51:36.023Z"),
}

This is all cool, but the post title is “Mongoose Populate”, what is Populate? For those familiar with MySQL or similar databases (RDBMS), one of the most used commands are the JOINS (INNER/LEFT/OUTER/RIGHT). All good but MongoDB does not have JOINS, so this is where Mongoose helps a lot. Imagine the following structure:

// Define some structure for our Post
const Post = new mongoose.Schema('Post', {
  title: {
    type: String,
    required: true
  },
  content: {
    type: String
  },
  comments: {
    type: [mongoose.Schema.Types.ObjectId],
    ref: 'Comment' // This will be a link for the Comments object
  }
}, {
  timestamp: true
})

// Define some structur for our Post Comments
const Comment = new mongoose.Schema('Comment', {
  content: {
    type: String
  }
}, {
  timestamp: true
})

The ref allows us to define a field that is a link to another collection and the type defines that is an array of MongoDB ObjectId.

Lets create and link some data:

// NOTE: not handling the Promises

const post = new Post({
  title: 'This is my first post',
  content: 'this is the content of my post'
}).save()

const comment = new Comment({
  content: 'this is the comment content'
}).save()

post.comments.push(comment)
post.update()

Now the real magic of Populate. Lets get the Post together with the Comment

// NOTE: not handling the Promises

Post
  .find({})
  .populate('comments')
  .exec()
  .then(posts => {
    console.log(posts)
  })

This will get something like this:

{
  "_id": ObjectId("5ae9b46ea22f8b4e049e1e5a"),
  "title": "This is my first post",
  "content": "this is the content of my post",
  "comments": [
    {
      "_id": ObjectId("5ae9b46dea22f84e049e1e5a"),
      "content": "this is the comment content",
      "createdAt" : ISODate("2018-06-07T16:51:36.022Z"),
      "updatedAt" : ISODate("2018-06-07T16:51:36.026Z"),
    }
  ],
  "createdAt" : ISODate("2018-06-07T16:51:36.023Z"),
  "updatedAt" : ISODate("2018-06-07T16:51:36.023Z"),
}

How easy is that :)

Share Comments
comments powered by Disqus