A Comprehensive Guide to Mongoose Models: Key Advantages and How to Use Them

Priyanshu PandeyPriyanshu Pandey
21 min read

Models are like special templates made from schema definitions. They let us create and manage documents (records) in MongoDB. Each item created with a model is called a document, and models help us easily add, find, and work with these documents in the database.

Example:

Imagine we want to create a database to store information about books. We start by defining a schema (a blueprint) for what each book should look like:

const mongoose = require('mongoose');

// Define the schema (blueprint) for a book
const bookSchema = new mongoose.Schema({
  title: String,
  author: String,
  pages: Number,
});

Then, we create a model from this schema. The model allows us to add, find, and manage books in our MongoDB database:

// Create a model using the schema
const Book = mongoose.model('Book', bookSchema);

Now, we can use this Book model to create a new book (called a "document" when it's added to MongoDB):

// Create a new document (book)
const myBook = new Book({
  title: 'The Great Gatsby',
  author: 'F. Scott Fitzgerald',
  pages: 180,
});

// Save the book to the database
myBook.save()
  .then(() => console.log('Book saved!'))
  .catch((error) => console.error('Error saving book:', error));

In this example:

  • bookSchema defines what a book should look like (title, author, and pages).

  • Book is the model that allows us to work with books in MongoDB.

  • myBook is a document created with the Book model, which we then save to the database.

AspectDocumentModel
DefinitionA single record in a MongoDB collection (like a row in SQL).A blueprint or class that defines the structure and behavior of documents.
StructureRepresents data as key-value pairs in a JSON-like format.Defined by a schema that specifies the structure, data types, and validation rules.
PurposeHolds actual data (e.g., user information).Provides methods to interact with the database (CRUD operations) and enforce structure.
InstanceAn instance of a model that corresponds to a specific record.A constructor that allows the creation of document instances.
InteractionYou perform operations (create, read, update, delete) directly on documents.You use models to create, read, update, and delete documents in a structured way.
LifecycleExists as a record in the database once created.Exists as a definition in your code, allowing you to create documents as needed.

What is Subdocument ?

A subdocument in MongoDB refers to a document that is nested within another document. This allows you to structure your data hierarchically and represents complex data relationships more naturally. Subdocuments can be used to group related data together, making it easier to manage and query

Key Characteristics of Subdocuments

  1. Nested Structure: Subdocuments are defined as fields within a parent document, allowing for a multi-level data structure.

  2. Schema Definition: When using Mongoose, you can define a schema for subdocuments just like you would for a top-level document. This allows for validation and structure enforcement.

  3. Operations: You can perform CRUD (Create, Read, Update, Delete) operations on subdocuments just like you do with top-level documents.

Example of Subdocuments

Consider a scenario where you have a User document that has an array of Address subdocuments:

  1. Defining the Schemas:
const mongoose = require('mongoose');

// Define the subdocument schema for Address
const addressSchema = new mongoose.Schema({
  street: String,
  city: String,
  state: String,
  zip: String
});

// Define the main document schema for User
const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  addresses: [addressSchema] // Array of Address subdocuments
});

// Create the User model
const User = mongoose.model('User', userSchema);
  1. Creating a User with Subdocuments:
const newUser = new User({
  name: "John Doe",
  email: "john@example.com",
  addresses: [
    {
      street: "123 Main St",
      city: "Anytown",
      state: "CA",
      zip: "12345"
    },
    {
      street: "456 Elm St",
      city: "Othertown",
      state: "NY",
      zip: "67890"
    }
  ]
});

// Save the user to the database
newUser.save()
  .then(() => console.log("User saved with addresses!"))
  .catch(error => console.error("Error saving user:", error));

Queries:

We learn queries through examples

Example User JSON Data

[
  {
    "name": "John Smith",
    "email": "john@example.com",
    "age": 30,
    "addresses": [
      {
        "street": "123 Elm St",
        "city": "Seattle",
        "state": "WA",
        "zip": "98101"
      }
    ]
  },
  {
    "name": "Jane Doe",
    "email": "jane@example.com",
    "age": 25,
    "addresses": [
      {
        "street": "456 Oak St",
        "city": "Portland",
        "state": "OR",
        "zip": "97205"
      },
      {
        "street": "789 Pine St",
        "city": "Portland",
        "state": "OR",
        "zip": "97205"
      }
    ]
  },
  {
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "age": 28,
    "addresses": [
      {
        "street": "321 Maple St",
        "city": "Los Angeles",
        "state": "CA",
        "zip": "90001"
      }
    ]
  },
  {
    "name": "Bob Brown",
    "email": "bob@example.com",
    "age": 35,
    "addresses": []
  },
  {
    "name": "Carol White",
    "email": "carol@example.com",
    "age": 32,
    "addresses": [
      {
        "street": "654 Cedar St",
        "city": "Chicago",
        "state": "IL",
        "zip": "60601"
      }
    ]
  }
]

—> Model.deleteMany()

You want to delete all users who are from the city "Portland".

Parameters

  • Filter (Required): An object specifying the conditions for the documents to delete.

  • Options (Optional): An object that can include:

    • collation: Language-specific rules for string comparison.

    • session: For transactions (if you're using MongoDB transactions).

    • writeConcern: Acknowledgment level from MongoDB for write operations.

    • limit: Maximum number of documents to delete (rarely used with deleteMany).

async function deleteUsersFromPortland() {
  try {
    const result = await User.deleteMany({ "addresses.city": "Portland" });
    console.log("Users deleted:", result.deletedCount); // This will return the number of deleted documents
  } catch (error) {
    console.error("Error deleting users:", error);
  }
}

// Call the function to execute the deletion
deleteUsersFromPortland();

Return Value

  • result Object: Contains:

    • deletedCount: Number of documents deleted based on the filter.

    • acknowledged: Boolean indicating if the delete operation was acknowledged.

Model.deleteOne()

Parameters

  • Filter (Required): An object specifying the condition for the document to delete.

    • Example: { name: "John Doe" } (This will delete the first user with the name "John Doe".)
  • Options (Optional): An object that can include:

    • session: For transactions (if you're using MongoDB transactions).

    • writeConcern: Acknowledgment level from MongoDB for write operations.

    • collation: Language-specific rules for string comparison.

2. Return Value

  • result Object: Contains:

    • deletedCount: Number of documents deleted (should be 0 or 1 for deleteOne).

    • acknowledged: Boolean indicating if the delete operation was acknowledged.

3. Situation

You want to delete a user whose name is "John Doe".

4. Code Example

javascriptCopy codeasync function deleteUserByName() {
  try {
    const filter = { name: "John Doe" }; // Condition for deletion
    const options = {}; // You can add options if needed

    const result = await User.deleteOne(filter, options);
    console.log("User deleted:", result.deletedCount); // Number of deleted documents (0 or 1)
  } catch (error) {
    console.error("Error deleting user:", error);
  }
}

// Call the function to execute the deletion
deleteUserByName();
  • Model.find()

  • Parameters

    • Filter (Optional): An object specifying the conditions for the documents you want to find. If omitted, all documents will be returned.

      • Example: { age: { $gt: 18 } } (Find users older than 18).
    • Projection (Optional): An object specifying which fields to include or exclude in the returned documents.

      • Example: { name: 1, email: 1 } (Only return the name and email fields).
    • Options (Optional): An object that can include various options to customize the query.

      • sort: An object specifying the sort order of the results.

      • limit: A number specifying the maximum number of documents to return.

      • skip: A number specifying how many documents to skip before returning results.

      • lean: If set to true, Mongoose will return plain JavaScript objects instead of Mongoose documents, which can improve performance.

2. Return Value

  • Promise: The method returns a promise that resolves to an array of documents that match the filter.

3. Situation

You want to find all users who are older than 18 and return only their names and email addresses.

4. Code Example

    async function findUsersOlderThan18() {
      try {
        const filter = { age: { $gt: 18 } }; // Condition to find users
        const projection = { name: 1, email: 1 }; // Fields to include
        const options = { sort: { age: 1 }, limit: 10 }; // Sort by age, limit to 10 results

        const users = await User.find(filter, projection, options);
        console.log("Found users:", users);
      } catch (error) {
        console.error("Error finding users:", error);
      }
    }

    // Call the function to execute the find operation
    findUsersOlderThan18();

Assuming the User model contains the following sample documents:

    [
      { "name": "Alice", "email": "alice@example.com", "age": 22 },
      { "name": "Bob", "email": "bob@example.com", "age": 19 },
      { "name": "Charlie", "email": "charlie@example.com", "age": 17 },
      { "name": "David", "email": "david@example.com", "age": 24 },
      { "name": "Eve", "email": "eve@example.com", "age": 20 }
    ]

The output from the findUsersOlderThan18 function would be:

     users: [
      { _id: "1", name: "Bob", email: "bob@example.com" },
      { _id: "2", name: "Alice", email: "alice@example.com" },
      { _id: "3", name: "Eve", email: "eve@example.com" },
      { _id: "4", name: "David", email: "david@example.com" }
    ]

Model.findById()

Parameters

  • id: The ID of the document you want to find. This is required.

  • projection (optional): Specifies which fields to include or exclude.

  • options (optional): Options to customize the query (e.g., lean, select, etc.).

Return Value

  • Promise: Resolves to the found document or null if no document is found.

Situation

You want to find a user by their unique ID.

Code Example

    async function findUserById(userId) {
      try {
        const user = await User.findById(userId);
        console.log("Found user:", user);
      } catch (error) {
        console.error("Error finding user by ID:", error);
      }
    }

    // Call the function with a sample user ID
    findUserById("60c72b2f9b1e8b3d88c9a4c2");

Expected Output

    user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice", email: "alice@example.com", age: 22 }

Model.findByIdAndDelete()

Parameters

  • id: The ID of the document you want to delete. This is required.

  • options (optional): Options for the query.

Return Value

  • Promise: Resolves to the deleted document or null if no document was found.

Situation

You want to delete a user by their unique ID.

Code Example

    async function deleteUserById(userId) {
      try {
        const deletedUser = await User.findByIdAndDelete(userId);
        console.log("Deleted user:", deletedUser);
      } catch (error) {
        console.error("Error deleting user by ID:", error);
      }
    }

    // Call the function with a sample user ID
    deleteUserById("60c72b2f9b1e8b3d88c9a4c2");

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice", email: "alice@example.com", age: 22 }

Model.findByIdAndRemove()

Parameters

  • id: The ID of the document you want to remove. This is required.

  • options (optional): Options for the query.

Return Value

  • Promise: Resolves to the removed document or null if no document was found.

Situation

You want to remove a user by their unique ID.

Code Example

    async function removeUserById(userId) {
      try {
        const removedUser = await User.findByIdAndRemove(userId);
        console.log("Removed user:", removedUser);
      } catch (error) {
        console.error("Error removing user by ID:", error);
      }
    }

    // Call the function with a sample user ID
    removeUserById("60c72b2f9b1e8b3d88c9a4c2");

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice", email: "alice@example.com", age: 22 }

Model.findByIdAndUpdate()

Parameters

  • id: The ID of the document you want to update. This is required.

  • update: An object specifying the fields to update. This is required.

  • options (optional): Options for the query (e.g., { new: true } to return the updated document).

Return Value

  • Promise: Resolves to the updated document or null if no document was found.

Situation

You want to update a user’s email by their unique ID.

Code Example

    async function updateUserEmailById(userId, newEmail) {
      try {
        const updatedUser = await User.findByIdAndUpdate(userId, { email: newEmail }, { new: true });
        console.log("Updated user:", updatedUser);
      } catch (error) {
        console.error("Error updating user by ID:", error);
      }
    }

    // Call the function with a sample user ID and new email
    updateUserEmailById("60c72b2f9b1e8b3d88c9a4c2", "newalice@example.com");

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice", email: "newalice@example.com", age: 22 }

Model.findOne()

Parameters

  • filter: An object specifying the conditions for the document to find. This is required.

  • projection (optional): Specifies which fields to include or exclude.

  • options (optional): Options to customize the query.

Return Value

  • Promise: Resolves to the found document or null if no document is found.

Situation

You want to find a user with a specific email.

Code Example

    async function findUserByEmail(email) {
      try {
        const user = await User.findOne({ email: email });
        console.log("Found user:", user);
      } catch (error) {
        console.error("Error finding user by email:", error);
      }
    }

    // Call the function with a sample email
    findUserByEmail("alice@example.com");

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice", email: "alice@example.com", age: 22 }

Model.findOneAndDelete()

Parameters

  • filter: An object specifying the conditions for the document to delete. This is required.

  • options (optional): Options for the query.

Return Value

  • Promise: Resolves to the deleted document or null if no document was found.

Situation

You want to delete a user with a specific email.

Code Example

    async function deleteUserByEmail(email) {
      try {
        const deletedUser = await User.findOneAndDelete({ email: email });
        console.log("Deleted user:", deletedUser);
      } catch (error) {
        console.error("Error deleting user by email:", error);
      }
    }

    // Call the function with a sample email
    deleteUserByEmail("alice@example.com");

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice", email: "alice@example.com", age: 22 }

Model.findOneAndReplace()

Parameters

  • filter: An object specifying the conditions for the document to replace. This is required.

  • replacement: An object specifying the new document that will replace the found document. This is required.

  • options (optional): Options for the query.

Return Value

  • Promise: Resolves to the replaced document or null if no document was found.

Situation

You want to completely replace a user’s document with a new one.

Code Example

    async function replaceUserByEmail(email, newUserData) {
      try {
        const replacedUser = await User.findOneAndReplace({ email: email }, newUserData);
        console.log("Replaced user:", replacedUser);
      } catch (error) {
        console.error("Error replacing user by email:", error);
      }
    }

    // Call the function with a sample email and new user data
    replaceUserByEmail("alice@example.com", { name: "Alice Smith", email: "newalice@example.com", age: 23 });

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice Smith", email: "newalice@example.com", age: 23 }

Model.findOneAndUpdate()

Parameters

  • filter: An object specifying the conditions for the document to update. This is required.

  • update: An object specifying the fields to update. This is required.

  • options (optional): Options for the query (e.g., { new: true } to return the updated document).

Return Value

  • Promise: Resolves to the updated document or null if no document was found.

Situation

You want to update a user's age by their email.

Code Example

    async function updateUserAgeByEmail(email, newAge) {
      try {
        const updatedUser = await User.findOneAndUpdate({ email: email }, { age: newAge }, { new: true });
        console.log("Updated user:", updatedUser);
      } catch (error) {
        console.error("Error updating user by email:", error);
      }
    }

    // Call the function with a sample email and new age
    updateUserAgeByEmail("newalice@example.com", 25);

Expected Output

     user: { _id: "60c72b2f9b1e8b3d88c9a4c2", name: "Alice Smith", email: "newalice@example.com", age: 25 }

Model.replaceOne()

Parameters

  • filter: An object specifying the conditions to match the document(s) to replace. This is required.

  • replacement: An object representing the new document that will replace the matched document(s). This is required.

  • options (optional): Options for the query (e.g., upsert, writeConcern, etc.).

Return Value

  • Promise: Resolves to an object containing information about the operation, including the number of documents matched and modified.

Situation

You want to replace a user with a specific email entirely.

Code Example

    async function replaceUserByEmail(email, newUserData) {
      try {
        const result = await User.replaceOne({ email: email }, newUserData);
        console.log("Replace result:", result);
      } catch (error) {
        console.error("Error replacing user:", error);
      }
    }

    // Call the function with a sample email and new user data
    replaceUserByEmail("newalice@example.com", { name: "Alice Smith", email: "newalice@example.com", age: 23 });

Expected Output

     result: { acknowledged: true, matchedCount: 1, modifiedCount: 1 }

Model.updateMany()

Parameters

  • filter: An object specifying the conditions for the documents to update. This is required.

  • update: An object specifying the fields to update. This is required.

  • options (optional): Options for the update operation (e.g., { multi: true } to update multiple documents).

Return Value

  • Promise: Resolves to an object containing information about the operation, including the number of documents matched and modified.

Situation

You want to update the age of all users who are currently 22 years old to 23.

Code Example

    async function updateUserAgeFrom22To23() {
      try {
        const result = await User.updateMany({ age: 22 }, { age: 23 });
        console.log("Update result:", result);
      } catch (error) {
        console.error("Error updating users:", error);
      }
    }

    // Call the function to update users' ages
    updateUserAgeFrom22To23();

Expected Output

     result: { acknowledged: true, matchedCount: 3, modifiedCount: 3 }

Model.updateOne()

Parameters

  • filter: An object specifying the conditions for the document to update. This is required.

  • update: An object specifying the fields to update. This is required.

  • options (optional): Options for the query (e.g., { upsert: true } to create a new document if no match is found).

Return Value

  • Promise: Resolves to an object containing information about the operation, including the number of documents matched and modified.

Situation

You want to update a specific user’s email by their unique ID.

Code Example

    async function updateUserEmailById(userId, newEmail) {
      try {
        const result = await User.updateOne({ _id: userId }, { email: newEmail });
        console.log("Update result:", result);
      } catch (error) {
        console.error("Error updating user by ID:", error);
      }
    }

    // Call the function with a sample user ID and new email
    updateUserEmailById("60c72b2f9b1e8b3d88c9a4c2", "updatedalice@example.com");

Expected Output

     result: { acknowledged: true, matchedCount: 1, modifiedCount: 1 }

Query Casting

Query casting in Mongoose refers to the process of transforming the query conditions (the parameters you provide to a query) into a format that can be processed by MongoDB. This involves taking the raw data from your application (such as strings, numbers, and objects) and converting them into a format that matches the schema defined in your Mongoose models.

Key Aspects of Query Casting

  1. Type Conversion:

    • Mongoose will automatically convert the types of query parameters based on the schema definitions. For example, if a field in your schema is defined as a number, and you query with a string, Mongoose will cast the string to a number.
  2. Default Values:

    • If your schema specifies default values for certain fields, these defaults will be applied during the casting process when creating or updating documents.
  3. Validation:

    • Mongoose will validate the values against the schema during casting. If a value does not meet the criteria defined in the schema (like a required field missing or a value being of the wrong type), Mongoose will throw a validation error.
  4. Query Modifiers:

    • Query casting also applies to query modifiers (like $gte, $lt, etc.). Mongoose ensures that the values used with these operators are in the correct format.

Example of Query Casting

Let's say you have a Mongoose model defined as follows:

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  age: { type: Number, required: true },
  email: { type: String, required: true, unique: true }
});

const User = mongoose.model('User', userSchema);

Example Query

When you perform a query like:

javascriptCopy codeconst ageQuery = "25"; // This is a string
User.find({ age: ageQuery }).exec();

Query Casting Process

  1. Type Conversion:

    • Mongoose will cast the string "25" to the number 25 because the age field in the schema is defined as a Number.
  2. Validation:

    • If you were to pass a non-numeric string (e.g., "twenty-five"), Mongoose would validate it against the schema and throw an error because it can't cast that string to a number.

The strictQuery option in Mongoose controls how Mongoose handles queries that include fields that are not defined in the schema. This option can be particularly useful in ensuring data integrity and maintaining clean queries.

strictQuery

  1. Default Behavior:

    • By default, Mongoose allows queries to include fields that are not defined in the schema. This means if you query for a field that doesn’t exist in the schema, Mongoose will simply ignore that field.
  2. Strict Mode:

    • When strictQuery is enabled (set to true), Mongoose will reject any queries that attempt to access fields not defined in the schema. This can help catch errors early and prevent potential issues related to unexpected data.

How to Use strictQuery

You can set the strictQuery option either globally when connecting to the MongoDB database or on a per-model basis.

Example of Setting strictQuery

Global Setting:

    const mongoose = require('mongoose');

    mongoose.set('strictQuery', true); // Enabling strictQuery globally

    mongoose.connect('mongodb://localhost/mydatabase', {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });

Per-Model Setting: You can also specify strictQuery directly in your schema options:

    javascriptCopy codeconst userSchema = new mongoose.Schema({
      name: { type: String, required: true },
      age: { type: Number, required: true },
    }, { strictQuery: true }); // Enabling strictQuery for this model

    const User = mongoose.model('User', userSchema);

Example Behavior

  1. With strictQuery: true: If you try to query for a field that doesn’t exist in the schema:

     javascriptCopy codeUser.find({ nonExistentField: 'someValue' });
    

    Mongoose will throw an error indicating that nonExistentField is not defined in the schema.

  2. With strictQuery: false (Default): The same query would simply ignore nonExistentField and return results based only on defined fields.

When to Use strictQuery

  • Data Integrity: If you want to ensure that only defined fields are queried, enabling strictQuery helps maintain integrity.

  • Debugging: It can aid in debugging queries by catching typos or unintended fields in your queries.

  • Cleaner Code: Helps in enforcing best practices by ensuring your queries align with your schema definitions.

Using Lean

In Mongoose, the .lean() method is used to make queries return plain JavaScript objects instead of Mongoose documents. This can improve performance and reduce memory usage, especially for read-heavy applications where you don’t need the additional features provided by Mongoose documents (like getters, setters, and other methods).

Benefits of Using .lean()

  1. Performance: Queries that use .lean() are faster because Mongoose skips the overhead of creating Mongoose document instances, which involves additional processing.

  2. Memory Usage: Since lean queries return plain objects, they use less memory, which can be beneficial when fetching large datasets.

  3. Simplicity: You get back simple objects that can be directly used in your application without needing to call any Mongoose methods.

When to Use .lean()

  • When you only need to read data and do not need to use Mongoose's document methods.

  • When performance is critical, especially in read-heavy applications.

  • When working with large datasets where reducing memory usage is important.

Example Usage of .lean()

User Schema

First, let’s define a simple User schema.

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: String,
  hobbies: [String],
});

const User = mongoose.model('User', userSchema);

Querying with .lean()

Here’s how to use .lean() in a query:

async function findUsers() {
  try {
    // Query to find all users and return plain JavaScript objects
    const users = await User.find().lean(); // Using .lean()

    console.log(users); // Output will be plain JavaScript objects
  } catch (error) {
    console.error('Error fetching users:', error);
  }
}

Example Output

Assuming you have the following documents in your users collection:

[
  { "_id": "1", "name": "Alice", "hobbies": ["reading", "gaming"] },
  { "_id": "2", "name": "Bob", "hobbies": ["coding", "hiking"] }
]

Using .lean() would result in output like this:

[
  { _id: '1', name: 'Alice', hobbies: [ 'reading', 'gaming' ] },
  { _id: '2', name: 'Bob', hobbies: [ 'coding', 'hiking' ] }
]

SUMMARY:

Method/ConceptPurposeAlternativeReturn Value
Model.deleteMany()Deletes multiple documents based on a filterModel.remove()Returns an object with the number of deleted documents.
Model.deleteOne()Deletes a single document based on a filterModel.findOneAndDelete()Returns the deleted document.
Model.find()Retrieves multiple documents that match a filterModel.findOne()Returns an array of documents or an empty array if none found.
Model.findById()Retrieves a single document by its IDN/AReturns the found document or null if not found.
Model.findByIdAndDelete()Finds and deletes a document by its IDN/AReturns the deleted document or null if not found.
Model.findByIdAndRemove()Finds and removes a document by its IDN/AReturns the removed document or null if not found.
Model.findByIdAndUpdate()Finds and updates a document by its IDN/AReturns the updated document or the original if new: false.
Model.findOne()Retrieves the first document that matches a filterN/AReturns the found document or null if none found.
Model.findOneAndDelete()Finds and deletes the first document that matches a filterN/AReturns the deleted document or null if none found.
Model.findOneAndReplace()Finds and replaces the first document that matches a filterN/AReturns the replaced document or null if none found.
Model.findOneAndUpdate()Finds and updates the first document that matches a filterN/AReturns the updated document or the original if new: false.
Model.replaceOne()Replaces a single document that matches a filterN/AReturns an object with the number of documents replaced and the original document.
Model.updateMany()Updates multiple documents based on a filterModel.updateOne()Returns an object with the number of documents modified.
Model.updateOne()Updates a single document based on a filterN/AReturns an object with the number of documents modified.
Using LeanImproves performance by returning plain JavaScript objects instead of Mongoose documents.N/AReturns an array of plain objects or a single object without Mongoose's methods.
Lean and PopulateAllows the use of .lean() with populate(), returning plain objects after populating references.N/AReturns plain objects that have populated fields.
When to Use LeanUse when retrieving data only (read operations) for better performance.N/AResults are plain JavaScript objects.
PluginsReusable functions that can extend Mongoose models with additional features.N/AVaries by plugin; can add methods or modify behavior.
BigIntsSupports JavaScript's BigInt type for handling very large integers in MongoDB.N/AReturns BigInt values instead of standard numbers.
Query CastingAutomatically converts query conditions to the appropriate types based on the schema.N/AReturns casted query conditions; helps ensure type safety.
Query SelectLimits the fields returned in the result set for queries.N/AReturns documents with only the specified fields included.
0
Subscribe to my newsletter

Read articles from Priyanshu Pandey directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Priyanshu Pandey
Priyanshu Pandey