Categories
MongoDB

Using MongoDB with Mongoose — Populate

Spread the love

To make MongoDB database manipulation easy, we can use the Mongoose NPM package to make working with MongoDB databases easier.

In this article, we’ll look at how to use Mongoose to manipulate our MongoDB database.

Populate

We can use the populate method to join 2 models together.

For example, we can write:

async function run() {
  const { createConnection, Types, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const personSchema = Schema({
    _id: Schema.Types.ObjectId,
    name: String,
    age: Number,
    stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
  });

  const storySchema = Schema({
    author: { type: Schema.Types.ObjectId, ref: 'Person' },
    title: String,
    fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
  });

  const Story = connection.model('Story', storySchema);
  const Person = connection.model('Person', personSchema);
  const author = new Person({
    _id: new Types.ObjectId(),
    name: 'James Smith',
    age: 50
  });

  author.save(function (err) {
    if (err) return handleError(err);

    const story1 = new Story({
      title: 'Mongoose Story',
      author: author._id
    });

    story1.save(function (err) {
      if (err) {
        return console.log(err);
      }

      Story.
        findOne({ title: 'Mongoose Story' }).
        populate('author').
        exec(function (err, story) {
          if (err) {
            return console.log(err);
          }
          console.log('author', story.author.name);
        });
    });
  });
}
run();

We created the Story and Person models.

The Story model references the Person model by setting author._id as the value of the author field.

Then we save both the author and story.

Then in the callback for story1.save , we get the Story entry with the exec method with a callback to get the data.

Then we can access the author’s name of the story with the story.author.name property.

The documents created with the models will be saved in their own collections.

Therefore the story.author.name ‘s value is 'James Smith' .

Setting Populated Fields

We can also set the author value directly by writing:

async function run() {
  const { createConnection, Types, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const personSchema = Schema({
    _id: Schema.Types.ObjectId,
    name: String,
    age: Number,
    stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
  });

  const storySchema = Schema({
    author: { type: Schema.Types.ObjectId, ref: 'Person' },
    title: String,
    fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
  });

  const Story = connection.model('Story', storySchema);
  const Person = connection.model('Person', personSchema);
  const author = new Person({
    _id: new Types.ObjectId(),
    name: 'James Smith',
    age: 50
  });

  author.save(function (err) {
    if (err) return handleError(err);

    const story1 = new Story({
      title: 'Mongoose Story',
    });

    story1.save(function (err) {
      if (err) {
        return console.log(err);
      }

      Story.findOne({ title: 'Mongoose Story' }, function (error, story) {
        if (error) {
          return console.log(error);
        }
        story.author = author;
        console.log(story.author.name);
      });
    });
  });
}
run();

We set story.author to author to link the author to the story .

And now story.author.name is 'James Smith' .

Checking Whether a Field is Populated

We can check whether a field is populated with the populated method.

For example, we can write:

async function run() {
  const { createConnection, Types, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const personSchema = Schema({
    _id: Schema.Types.ObjectId,
    name: String,
    age: Number,
    stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
  });

  const storySchema = Schema({
    author: { type: Schema.Types.ObjectId, ref: 'Person' },
    title: String,
    fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
  });

  const Story = connection.model('Story', storySchema);
  const Person = connection.model('Person', personSchema);
  const author = new Person({
    _id: new Types.ObjectId(),
    name: 'James Smith',
    age: 50
  });

  author.save(function (err) {
    if (err) return handleError(err);

    const story1 = new Story({
      title: 'Mongoose Story',
    });

    story1.save(function (err) {
      if (err) {
        return console.log(err);
      }

      Story.findOne({ title: 'Mongoose Story' }, function (error, story) {
        if (error) {
          return console.log(error);
        }
        story.author = author;
        console.log(story.populated('author'));
      });
    });
  });
}
run();

We get the ID of the author that the store is populated with.

We call depopulate to unlink the author and the story .

For example, we can write:

async function run() {
  const { createConnection, Types, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const personSchema = Schema({
    _id: Schema.Types.ObjectId,
    name: String,
    age: Number,
    stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
  });

  const storySchema = Schema({
    author: { type: Schema.Types.ObjectId, ref: 'Person' },
    title: String,
    fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
  });

  const Story = connection.model('Story', storySchema);
  const Person = connection.model('Person', personSchema);
  const author = new Person({
    _id: new Types.ObjectId(),
    name: 'James Smith',
    age: 50
  });

  author.save(function (err) {
    if (err) return handleError(err);

    const story1 = new Story({
      title: 'Mongoose Story',
    });

    story1.save(function (err) {
      if (err) {
        return console.log(err);
      }

      Story.findOne({ title: 'Mongoose Story' }, function (error, story) {
        if (error) {
          return console.log(error);
        }
        story.author = author;
        console.log(story.populated('author'));
        story.depopulate('author');
        console.log(story.populated('author'));
      });
    });
  });
}
run();

We call the depopulate method to unlink the author and story.

Now when we log the value of populated again, we see undefined .

Conclusion

We can join 2 documents together by referencing one document’s ID with the other.

Then we can use Mongoose’s method to check whether they’re linked.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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