Categories
MongoDB

Using MongoDB with Mongoose — Document Validation

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.

Validation

We can validate documents before saving by using the validate method.

For example, we can write:

const { runInContext } = require('vm');

async function run() {
  const mongoose = require('mongoose');
  const connection = mongoose.createConnection('mongodb://localhost:27017/test');
  const schema = new mongoose.Schema({ name: 'string', size: 'string' });
  const Tank = connection.model('Tank', schema);
  let t = new Tank({ name: 'foo', size: 'small' });
  await t.validate();
  let t2 = new Tank({ name: 'foo', size: -1 });
  await t2.validate();
}
run();

validate is run internally so we don’t have to run it ourselves.

We can set the runValidators property explicitly to control whether we want to run the validator:

const { runInContext } = require('vm');

async function run() {
  const mongoose = require('mongoose');
  const connection = mongoose.createConnection('mongodb://localhost:27017/test');
  const schema = new mongoose.Schema({ name: 'string', size: 'string' });
  const Tank = connection.model('Tank', schema);
  Tank.updateOne({}, { size: -1 }, { runValidators: true });
}
run();

Overwriting

We can overwrite a document.

For example, we can write:

const { runInContext } = require('vm');

async function run() {
  const mongoose = require('mongoose');
  const connection = mongoose.createConnection('mongodb://localhost:27017/test');
  const schema = new mongoose.Schema({ name: 'string', size: 'string' });
  const Tank = connection.model('Tank', schema);
  const doc = await Tank.findOne({ });
  doc.overwrite({ name: 'James' });
  await doc.save();
}
run();

to call the overwrite method to change the first tanks document with the name field set to 'James' .

Subdocuments

Subdocuments are documents that are embedded in other documents.

We can nest schemas in other schemas.

For example, we can write:

const { runInContext } = require('vm');

async function run() {
  const mongoose = require('mongoose');
  const connection = mongoose.createConnection('mongodb://localhost:27017/test');
  const childSchema = new mongoose.Schema({ name: 'string' });
  const parentSchema = new mongoose.Schema({
    children: [childSchema],
    child: childSchema
  });
  const Child = await connection.model('Child', childSchema);
  const Parent = await connection.model('Parent', parentSchema);
  const parent = new Parent({ children: [{ name: 'Matt' }, { name: 'Sarah' }] })
  await parent.save();
}
run();

We created the Child and Parent schemas with the Child schema embedded in the Parent schema.

The children property has an array of documents that fie the Child schema.

When we call save on the parent , everything embedded inside will also be saved.

We can watch the validate and save events for each schema.

For example, we can write:

const { runInContext } = require('vm');

async function run() {
  const mongoose = require('mongoose');
  const connection = mongoose.createConnection('mongodb://localhost:27017/test');
  const childSchema = new mongoose.Schema({ name: 'string' });
  const parentSchema = new mongoose.Schema({
    children: [childSchema],
    child: childSchema
  });

  childSchema.pre('validate', function (next) {
    console.log('2');
    next();
  });

  childSchema.pre('save', function (next) {
    console.log('3');
    next();
  });

  parentSchema.pre('validate', function (next) {
    console.log('1');
    next();
  });

  parentSchema.pre('save', function (next) {
    console.log('4');
    next();
  });
  const Child = await connection.model('Child', childSchema);
  const Parent = await connection.model('Parent', parentSchema);
  const parent = new Parent({ children: [{ name: 'Matt' }, { name: 'Sarah' }] })
  await parent.save();
}
run();

We see that they have the number logged.

They should run in the order in the same order the numbers are in.

So first the parent is validated, then the children are validated.

The children documents are saved, and then the parent is saved.

Conclusion

Mongoose comes with document validation built-in.

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 *