Style:
Original
font-size
columns
#

Recommended

Schema Definition
Connecting to MongoDB
Creating Models
Defining Schemas with Mongoose Schema Types
.save() Method for Saving Documents in Mongoose
.find() Method for Querying Documents in Mongoose
Updating documents using .updateOne(), .updateMany(), and findByIdAndUpdate()
Deleting documents using .deleteOne(), .deleteMany(), and findByIdAndDelete()
Mongoose Middleware (Pre/Post Hooks)
Mongoose Validation
Populating Referenced Documents Using populate() method
Mongoose Virtuals
Indexing in Mongodb with mongoose
'Lean' Queries
terms and conditions
privacy policy
contact

mongoose

Author:Eddie A.
Column 1

Applying a Plugin to a Schema

Plugins in Mongoose are reusable sets of schema and model options that can be applied globally or on specific schemas. They help encapsulate common functionality, such as timestamps, into re-usable components.

// Define the plugin const timestampPlugin = require('./plugins/timestamp'); // Apply the plugin to a schema const userSchema = new mongoose.Schema({ name: String, }); userSchema.plugin(timestampPlugin);

Plugin Hooks and Middleware

Mongoose allows you to define middleware functions that execute before or after certain operations. These are useful for tasks like validation, encryption, logging, etc. You can also use plugin hooks to add reusable functionality across multiple schemas.

// Example of using pre-save middleware userSchema.pre('save', function(next) { // perform some actions before saving the user next(); });

Using Third-Party Plugins with Mongoose

Mongoose allows the use of third-party plugins to extend its functionality. These can be used for adding custom validation, virtuals, middleware functions, and more. To use a plugin in your schema definition, simply call the `schema.plugin()` method.

// Example using a hypothetical timestamp plugin const mongoose = require('mongoose'); const timestampPlugin = require('./timestamp-plugin'); // Define schema const userSchema = new mongoose.Schema({ name: String }); userSchema.plugin(timestampPlugin);

Use Only Necessary Plugins

Only use plugins that are necessary for your application. Using unnecessary plugins can bloat the codebase and lead to performance issues.

// Example of using a Mongoose plugin const mongoose = require('mongoose'); const timestampPlugin = require('./plugins/timestamp'); mongoose.plugin(timestampPlugin);

Built-in Mongoose Plugins (e.g., timestamps)

Mongoose provides built-in plugins that can be used to add pre-defined functionality. One such plugin is 'timestamps' which automatically adds createdAt and updatedAt fields to the schema. This simplifies tracking when documents are created or modified.

// Example of using timestamps plugin const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ username: String, }, { timestamps: true });

Differences Between Global and Instance Level plugins

Global plugins are defined on the schema level and apply to all instances of a model, while instance-level plugins are applied directly to specific document instances.

// Define global plugin const timestampPlugin = require('./plugins/timestamp'); schema.plugin(timestampPlugin); // Apply instance-level plugin const doc = new MyModel(); doc.myInstanceLevelFunction()

Creating a Mongoose Plugin

Mongoose plugins are reusable sets of schema and model methods that can be added to any schema. They provide an easy way to add common functionality across multiple schemas.

// Define the plugin function const myPlugin = (schema, options) => { // Add custom methods or hooks to the schema here }; // Apply the plugin to a specific schema mySchema.plugin(myPlugin);

Introduction to Mongoose Plugins

Mongoose plugins are reusable sets of schema and model functionality that can be added to a Mongoose schema. They allow you to add pre-defined features or methods across multiple schemas, making your code more modular and maintainable.

// Define the plugin const myPlugin = (schema) => { // Add custom functionality here }; // Use the plugin in a schema mySchema.plugin(myPlugin);

Middleware Functions

Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. They can perform tasks, modify requests or responses, end a request-response cycle, call another middleware function in the stack, etc.

// Example of a simple middleware function function myMiddleware(req, res,next) { // Perform some task here next(); }

Types of Middleware in Mongoose

Mongoose supports four types of middleware: document middleware, model middleware, aggregate middleware, and query helpers. Document middleware is executed before or after a specific operation on an instance (i.e., a document). Model middlewares are for operations at the schema level such as 'init', 'validate', etc. Aggregate middlware allows defining functions that execute when calling `aggregate()` function. Query helper methods enable adding custom static methods to models.

// Example of using pre-save hook schema.pre('save', async function(next) { // Perform some actions before saving the document next(); });

Order of Execution for Multiple Middlewares

When using multiple middlewares in Mongoose, the order of execution is crucial. Middlewares are executed serially based on their registration sequence. Use next() to move to the next middleware or end the process.

// Example schema.pre('save', function(next) { // Do something before saving next(); });

Defining and Using Custom Middleware Functions

Custom middleware functions can be defined using the `use` method on a schema. These functions are executed before or after certain operations such as validation, saving, updating, etc. They provide a way to perform custom logic or modify data during these operations.

// Define custom pre-save middleware schema.pre('save', function(next) { // Perform some logic before saving next(); });

Error Handling in Middlewares

When creating custom middleware for error handling, use the 'next' function with an argument to pass errors. Use a conditional statement to check if there is an error and then call next(error) within the middleware. Always define your error-handling middlewares last after all other app.use() and routes.

// Custom Error Handling Middleware app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); });

Global Middleware vs. Document Middleware

Global middleware functions are defined on the schema and apply to all documents in a collection, while document middleware functions are specific to individual documents.

// Global Middleware schema.pre('save', function(next) { // Do something before saving next(); }); // Document Middleware schema.methods.methodName = function() { // Define method for individual document };

Use Middleware for Cross-cutting Concerns

Middleware can be used to handle common tasks such as logging, authentication, error handling, and input validation. This helps in keeping the codebase clean by separating concerns and promoting reusability.

// Example of using middleware const express = require('express'); const app = express(); app.use((req, res, next) => { console.log('Logging request...'); next(); // Pass control to the next middleware function });

Using Async/Await with Mongoose middleware functions

When using async/await with Mongoose middleware, you need to remember that the next() function is not automatically called. You must explicitly call it after your asynchronous operation completes. Also, make sure to handle any errors by wrapping your code in a try-catch block.

const UserSchema = new mongoose.Schema({ name: String, }); UserSchema.pre('save', async function(next) { try{ // Perform some asynchronous operation here await somethingAsync(); // Remember to use 'await' n next(); // Call 'next' when done } catch(err){ c onsole.error(err); // Handle error appropriately } });

find()

The find() method is used to retrieve documents from a MongoDB collection. It takes an optional query object as its parameter, which allows you to filter the results based on specific criteria. If no query object is provided, it will return all documents in the collection.

// Find all documents Model.find() // Find with a query Model.find({ key: value })

sort()

The sort() method is used to specify the sorting order for query results in Mongoose. It takes an object as a parameter, where each key represents a field and its value determines the sorting order (1 for ascending, -1 for descending). Multiple fields can be specified to create compound sorts.

.find().sort({ fieldName: sortOrder })
Column 2

Select

The select method is used to specify the fields that should be returned in the query result. It allows you to control which fields are retrieved from a document, helping reduce network overhead and improve performance.

.select('field1 field2')

Limit

The limit() function is used to restrict the number of documents returned by a query. It takes an integer as its argument, representing the maximum number of documents to be returned.

.find().limit(5) // Returns only up to 5 documents

Where Query

The 'where' query in Mongoose allows you to specify conditions for the documents returned by a find() or findOne() method. It is useful for filtering data based on specific criteria.

.find().where('field').equals(value)

Populate

The populate method in Mongoose is used to fill references from other collections. It allows you to retrieve documents referenced by a specific field and replace the specified path with actual data.

.populate('fieldName')

Sort

Mongoose provides the ability to sort query results based on one or more fields. Use the `sort()` method in combination with `-1` for descending order and `1` for ascending order. The sorting is applied after all other operations like filtering, projecting, etc.

.find().sort({ fieldName: -1 }) // Sorts by 'fieldName' in descending order

$and and $or operators for complex conditions

The $and operator performs a logical AND operation on an array of two or more expressions, returning true only if all the expressions are true. The $or operator performs a logical OR operation on an array of two or more expressions, returning true if any expression is true.

// Using Mongoose to find documents matching multiple conditions Model.find({ $and: [ { condition1 }, { condition2 } ] });

$elemMatch operator for array filtering

The $elemMatch operator is used to query and filter documents that contain arrays. It ensures that at least one element in the array matches all the specified criteria. This can be useful when querying embedded documents within an array field.

// Find documents where 'scores' contains a subdocument with both 'type' equal to 'quiz' and 'score' greater than or equal to 90 Model.find({ scores: { $elemMatch: { type: \"quiz\", score: { $gte : 90 } } }})

Count documents with count() method

The count() method is used to retrieve the number of documents that match a query. It takes a query as an optional parameter and returns the count of matching documents. If no query is provided, it returns the total document count in the collection.

// Count all documents in 'users' collection const userCount = await User.count(); // Count specific documents based on condition const activeUserCount = await User.count({ isActive: true });

Number

In Mongoose, the Number schema type is used to define a path for numeric values. It can be configured with options such as min, max, and default values. When defining a number field in a Mongoose schema, you can specify additional validation rules using 'min' and 'max'. For example: { age: { type: Number, min: 18 } }.

// Define a Mongoose Schema with a number field const userSchema = new mongoose.Schema({ age: { type : Number, required : true, min : [0,'Age must be greater than or equal to zero'] } });

Buffer

Buffers are Node.js objects used to represent binary data. They act as a temporary storage for raw data during the transmission of files or when working with streams. Buffers can be converted to strings and vice versa using encoding methods.

// Creating a buffer from string const buf = Buffer.from('Hello, World!', 'utf-8'); // Converting buffer to string console.log(buf.toString('utf-8'));

String in Mongoose

In Mongoose, the String schema type is used to define a path for storing string values. It can be configured with additional options such as required, default value, and validation rules using built-in or custom validators.

// Defining a 'name' field of type String const userSchema = new mongoose.Schema({ name: { type: String, required: true, unique: true } });

Date in Mongoose

Mongoose has a built-in Date schema type for handling dates. Dates can be set as default values, validated against min and max limits, or used with custom validation logic.

// Example of using the Date schema type const eventSchema = new mongoose.Schema({ date: { type: Date, required: true, default: Date.now() } });

Boolean

In Mongoose, the Boolean data type represents a true/false value. It is commonly used to store binary states such as 'active' or 'inactive'. When defining a schema in Mongoose, you can use the type key with the value set to Boolean.

// Define a schema with a field of type boolean const userSchema = new mongoose.Schema({ isActive: {type: Boolean} });

ObjectId

The ObjectId is a unique identifier for documents in MongoDB. It consists of a timestamp, machine id, process id, and counter. The first four bytes represent the timestamp in seconds since the Unix epoch.

// Creating an ObjectId const { ObjectID } = require('mongodb'); const objectId = new ObjectID();

Schema Types

Mongoose provides several built-in SchemaTypes to define the data structure for each field in a document. These include String, Number, Date, Buffer (for storing binary data), Boolean, Mixed (allows any type of data), ObjectId and Array.

// Example defining an array field const userSchema = new mongoose.Schema({ name: String, age: Number, hobbies: [String] });

Mixed

The 'Mixed' schema type in Mongoose allows flexibility by storing data that doesn't have a fixed structure. It can hold any arbitrary data types, making it suitable for scenarios where the shape of the documents may vary.

// Example of using Mixed type const mongoose = require('mongoose'); const Schema = mongoose.Schema; // Define a schema with mixed type field const mySchema = new Schema({ dynamicData: {} });

Creating a Mongoose model

Mongoose provides a straightforward way to create models for your MongoDB collections. Models are constructors compiled from Schema definitions and represent documents in the database.

// Define schema const { Schema } = mongoose; const userSchema = new Schema({ name: String, age: Number }); // Create model using schema const User = mongoose.model('User', userSchema);

Defining schema for the model

In Mongoose, a schema defines the structure of documents within a collection. It includes fields and their types along with options such as default values, validation rules, etc. Schemas are used to create models which can be instantiated into document instances.

// Define a simple user schema const userSchema = new mongoose.Schema({ name: String, email: { type: String, required: true } });

Specifying field types and validations

Mongoose allows you to specify the data type of each field in a schema, along with various validation options. This helps ensure that only valid data is stored in the database. Commonly used validators include required, min/max length, enum (for specifying allowed values), match (to validate against a regular expression), and custom validator functions.

// Example of defining a schema with field types and validations const userSchema = new mongoose.Schema({ name: { type: String, required: true }, age: { type: Number, min: [18,'Must be at least 18 years old'] } });

Using plugins in models

Mongoose allows the use of plugins to add reusable functionality to your schema. Plugins can be used for adding fields, methods, statics or virtuals to a model.

// Define and apply a plugin const timestampPlugin = require('./plugins/timestamp'); schema.plugin(timestampPlugin);

Setting up middleware/hooks for pre/post actions

Mongoose allows you to define middleware functions that execute before or after certain operations such as validation, saving, and removing. Use the `pre` method to register a function to run before the specified operation and use the `post` method for running it after. These hooks are useful for tasks like data manipulation, logging, authentication checks.

// Pre save hook schema.pre('save', function(next) { // Your code here... next(); });

Adding methods to the model

You can add instance and static methods to your Mongoose models. Instance methods operate on an individual document, while static methods work at the Model level. Use `schema.methods.methodName` for adding instance method and `schema.statics.methodName` for adding a static method.

// Adding an instance method const schema = new mongoose.Schema({ name: String, }); schema.methods.speak = function () { const greeting = this.name ? 'My name is ' + this.name : \"I don't have a name\"; console.log(greeting); };

Including virtual properties in the schema

Virtuals are document properties that you can get and set but do not persist to MongoDB. They're great for formatting or combining fields, as well as creating new data on the fly.

// Define a virtual property const personSchema = new Schema({ firstName: String, lastName: String }); personSchema.virtual('fullName').get(function() { return this.firstName + ' ' + this.lastName; });

Applying options such as timestamps

Mongoose provides the option to include a createdAt and updatedAt field in your schema, which automatically updates these fields when documents are created or modified. This is achieved by setting the 'timestamps' option to true when defining the schema.

// Example of applying timestamps const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ username: String, }, { timestamps: true });
Column 3

Defining a Schema

In Mongoose, a schema defines the structure of documents within a collection. It specifies the fields and their types along with any additional options such as default values or validation rules. Schemas are used to create models which can then be used to perform CRUD operations on MongoDB collections.

// Define a simple schema const { Schema } = require('mongoose'); const userSchema = new Schema({ name: String, age: Number });

Data Types and Validation

Mongoose provides various data types such as String, Number, Date, Boolean, etc., for defining schema paths. It also offers built-in validators like required, min/max length, enum values to enforce data validation rules. Custom validators can be defined using the validate property in a schema path definition.

// Defining a Mongoose Schema with Data Types and Validators const userSchema = new mongoose.Schema({ name: { type: String , required: true }, age: { type : Number , min : [18,'Must be at least 18 years old'] } });

Required Fields

In Mongoose, you can specify that certain fields are required using the 'required' property in a schema definition. This ensures that documents must contain these fields before they can be saved to the database. If a document is missing a required field, Mongoose will throw a validation error.

// Example of defining a required field in Mongoose const userSchema = new mongoose.Schema({ name: { type: String, required: true } });

Error Messages for Validation Failures

Mongoose provides built-in error messages for validation failures. These include 'required', 'minlength', 'maxlength', and more, which can be customized as needed.

// Example of customizing error message const schema = new Schema({ name: { type: String, required: true, minlength: [3, 'Name must be at least 3 characters'] } })

Schema Options (e.g., strict)

The 'strict' option in Mongoose schema determines whether fields other than those defined in the schema are ignored or throw an error. Setting 'strict: true' means that any data not specified in the schema will be discarded, while setting it to false allows for additional data.

// Example of using strict option const sampleSchema = new Schema({ name: String, age: Number }, { strict: true });

Custom Validators

Mongoose allows you to define custom validators for your schema. You can create reusable validation functions and apply them to specific fields in your schema. Custom validators are useful for enforcing complex business rules or data requirements.

// Define a custom validator function const myValidator = (value) => { if (/* some condition */) { return true; } return false; }; // Apply the custom validator to a field in the schema const mySchema = new Schema({ customField: { type: String, validate: [myValidator, 'Invalid value'] }, });

Asynchronous Custom Validators

Mongoose allows you to define custom validators that can perform asynchronous validation. This is useful for scenarios where the validation requires querying a database or making an API call. To create an asynchronous custom validator, use a function with the `validate` property set to true and accept a callback as its last argument.

// Example of defining an asynchronous custom validator const userSchema = new Schema({ email: { type: String, validate: { isAsync: true, validator: function(value, isValid) { setTimeout(() => { // Simulating async operation const result = value && value.length > 0; // Perform actual async check here isValid(result); }, 5); } type: tString});

Inbuilt Validators

Mongoose provides inbuilt validators for data validation before saving it to the database. These include built-in validator types such as required, min, max, enum, match (regex), and more.

// Example of using inbuilt validators const userSchema = new mongoose.Schema({ name: { type: String, required: true }, age: { type: Number, min: [18,'Must be at least 18'], max:[100,'Cannot exceed 100'] } });

Populate Method

The populate method in Mongoose is used to automatically replace specified paths with documents from other collections. It allows for seamless integration of data across different models and simplifies querying by eliminating the need for manual population.

.populate('author', 'name -_id')

Update Method

The update method in Mongoose allows you to modify existing documents in MongoDB. It takes two parameters: the query to find the document(s) and an object containing the updates.

.update({ name: 'John' }, { age: 30 })

Creating New Documents

Mongoose provides a simple way to create new documents using models. Use the 'save' method on a new instance of the model to persist it in MongoDB. You can also use the 'create' method directly on the model class, which combines creating and saving into one step.

// Using save method const newUser = new User({ name: 'John', age: 25 }); await newUser.save(); // Using create method const createdUser = await User.create({ name: 'Jane', age: 30 });

Population

Populating referenced document fields during a read operation allows you to retrieve documents from other collections and include them in the result. This is useful for avoiding multiple database queries when working with related data.

.populate('fieldName')

Mongoose Delete Methods

Mongoose provides several methods to delete documents from a collection, including findByIdAndDelete(), findOneAndRemove(), and deleteOne(). These methods allow you to remove specific documents based on conditions or criteria.

// Example using findByIdAndDelete const result = await YourModel.findByIdAndDelete(id);

Middleware Hooks

Mongoose provides pre-save and post-save hooks that allow you to run custom logic before or after CRUD operations. These hooks are useful for tasks such as data validation, encryption, logging, etc.

// Pre-Save Hook schema.pre('save', function(next) { // Custom logic here next(); }); // Post-Save Hook schema.post('save', function(doc) { // Custom logic here });

Validation in Mongoose

Mongoose provides a powerful schema-based validation feature to ensure data integrity. You can define validators for each field, including built-in and custom ones. Use the 'validate' property within your schema definition to specify validation rules.

// Example of defining a validator for a field const userSchema = new Schema({ age: { type: Number, validate: { validator: function(v) { return v > 0; }, message: 'Age must be greater than zero' } } });

Bulk Operations

Mongoose provides efficient methods for performing bulk insert, update, and delete operations. These operations can be performed using Mongoose's built-in functions like 'insertMany', 'updateMany', and 'deleteMany'. Performing these bulk operations helps in optimizing database interactions by reducing the number of individual queries.

// Example of Bulk Insert const data = [{ name: 'John' }, { name: 'Jane' }]; Model.insertMany(data);

Defining a schema with mongoose.Schema() method

The `mongoose.Schema()` method is used to define the structure of documents within a collection. It takes an object that defines the shape of your documents, including properties and their types. You can also specify additional options such as default values, validation rules, and custom getters/setters.

// Define a simple schema const userSchema = new mongoose.Schema({ name: String, age: Number });

Installing Mongoose

To install Mongoose, use npm (Node Package Manager) by running the command 'npm install mongoose' in your terminal. This will download and add the Mongoose package to your Node.js project. Make sure you have MongoDB installed and running before using Mongoose.

$ npm install mongoose

Creating a model from the schema using mongoose.model() method

The mongoose.model() method takes two parameters: the singular name of the collection and the schema. It returns a Model, which can be used to perform CRUD operations on that collection. The first parameter should be in singular form (e.g., 'User' for a users collection). If you don't specify an existing MongoDB connection when calling this function, Mongoose will create one by default.

// Define userSchema const userSchema = new Schema({ name: String, age: Number }); // Create User model based on userSchema const User = mongoose.model('User', userSchema);

Connecting to MongoDB using Mongoose

Mongoose provides a connect method to establish the connection with MongoDB. The connect method takes a URI as its first argument, followed by optional options and callback function. It also supports multiple connections by creating separate instances of mongoose.

// Establishing connection const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/myDatabase', { useNewUrlParser: true });

Handling Connection Errors

When connecting to MongoDB using Mongoose, you can handle connection errors by listening for the 'error' event on the mongoose.connection object. You can also use try-catch blocks when establishing connections to catch any potential errors. Additionally, setting up retry logic or implementing error handling middleware in your Node.js application can help manage and recover from connection errors.

// Handling connection error example mongoose.connect('mongodb://localhost/myapp', { useNewUrlParser: true }); mongoose.connection.on('error', (err) => { console.error(`Mongoose default connection error: ${err}`); });

Importing Mongoose into Node.js app

To use Mongoose in a Node.js application, first install it using npm: 'npm install mongoose'. Then, require the mongoose module in your code to create a connection and define schemas for MongoDB. Use the connect() method to establish a connection with your MongoDB database.

// Importing Mongoose const mongoose = require('mongoose'); // Connecting to MongoDB using Mongoose mongoose.connect('mongodb://localhost/my_database', {useNewUrlParser: true});

Establishing Default Connection

Mongoose allows you to establish a default connection for models and schemas using the `mongoose.connect()` method. This is typically done when setting up your application, such as in the main entry file. The default connection can be reused across multiple modules by importing mongoose.

// Example of establishing a default connection const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/myDatabase', { useNewUrlParser: true, useUnifiedTopology: true });

Closing the database connection

It's important to close the Mongoose connection when your Node.js application is shutting down or no longer needs to interact with MongoDB. This prevents memory leaks and ensures that all operations are completed before exiting.

// Close the Mongoose connection mongoose.connection.close(() => { console.log('Connection closed'); });
https://www.cheatrepo.com/sheet/mongoose-55b564
Last Updated: Tue Jul 23 2024

Press space bar to start a drag. When dragging you can use the arrow keys to move the item around and escape to cancel. Some screen readers may require you to be in focus mode or to use your pass through key