CodingNic

Mongoose: Schemas and Models

Models and Connecting

Mongoose: Schemas and Models 15 min read

Models and Connecting

Objectives

By the end of this lesson, you should be able to:

  • Turn a Mongoose schema into a usable model
  • Connect Mongoose to a real MongoDB database
  • Perform basic CRUD through a Mongoose model instead of the native driver

๐Ÿ’ก Why this matters: A schema alone (last lesson) doesn’t talk to a database. This lesson turns it into a model, the object every query in the rest of this course actually calls.

โš ๏ธ A note on verification: as throughout the MongoDB half of this course, this tooling has no route to a local MongoDB server. The code below reflects Mongoose’s stable, current, documented API. Try it yourself, on your own machine, against a real MongoDB server.

Project File Structure

text
mongoose-intro/
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ .env
โ”œโ”€โ”€ models/
โ”‚   โ””โ”€โ”€ Student.js
โ””โ”€โ”€ index.js

Connecting to MongoDB

javascript
// index.js
require('dotenv').config();
const mongoose = require('mongoose');

async function main() {
  await mongoose.connect(process.env.MONGODB_URI);
  console.log('Connected to MongoDB with Mongoose!');
}

main();
text
# .env
MONGODB_URI=mongodb://localhost:27017/school
bash
node index.js
text
Connected to MongoDB with Mongoose!

mongoose.connect() is the Mongoose equivalent of Module 7’s MongoClient.connect(), and follows the same environment-variable pattern from Module 1, Lesson 5, the connection string lives in .env, never hard-coded.

Creating a Model

javascript
// models/Student.js
const mongoose = require('mongoose');

const studentSchema = new mongoose.Schema({
  name: { type: String, required: true },
  grade: { type: Number, required: true }
});

module.exports = mongoose.model('Student', studentSchema);

mongoose.model('Student', studentSchema) registers the model under the name 'Student', and, by convention, Mongoose stores its documents in a MongoDB collection named students, lowercased and pluralized automatically, the same naming convention Prisma uses for migrated tables (Module 4).

Using the Model

javascript
// index.js
require('dotenv').config();
const mongoose = require('mongoose');
const Student = require('./models/Student');

async function main() {
  await mongoose.connect(process.env.MONGODB_URI);

  const student = await Student.create({ name: 'Erin', grade: 9 });
  console.log(student);

  const all = await Student.find();
  console.log(all);

  await mongoose.connection.close();
}

main();
text
{
  _id: new ObjectId('65f1a2b3c4d5e6f7a8b9c0d1'),
  name: 'Erin',
  grade: 9,
  __v: 0
}
[
  {
    _id: new ObjectId('65f1a2b3c4d5e6f7a8b9c0d1'),
    name: 'Erin',
    grade: 9,
    __v: 0
  }
]

Student.create() and Student.find() read noticeably closer to Prisma’s prisma.student.create() and prisma.student.findMany() than to the native driver’s students.insertOne() and students.find().toArray(), this is exactly the convenience an ORM/ODM layer adds. The __v field is Mongoose’s own internal version key, used for tracking document revisions, safe to ignore for now.

Try It

  1. Create a models/Product.js file, define a schema, and export a model with mongoose.model('Product', productSchema).
  2. Connect to MongoDB with mongoose.connect(), using a connection string from .env.
  3. Create a document with Product.create(), and read it back with Product.find().
  4. Explain, in your own words, what collection name Mongoose would use for a model named Order.

Recap

  • mongoose.model(name, schema) turns a schema into a model, Mongoose derives the actual MongoDB collection name automatically (lowercased, pluralized).
  • mongoose.connect() takes a connection string, loaded from .env, exactly like every other database connection in this course.
  • A Mongoose model’s methods (create, find, and more) read close to Prisma Client’s API, both sit on top of a lower-level driver doing the actual work.

Next lesson: validation, rejecting bad data before it ever reaches the database.