Sling Academy
Home/Node.js/Understanding the Map schema type in Mongoose

Understanding the Map schema type in Mongoose

Last updated: December 30, 2023

Overview

Maps in Mongoose are a schema type that allows you to define arbitrary key-value pairs within a document, offering flexibility for data structures that need dynamic keys. This tutorial will guide you through the utilization of Map schema type with practical examples.

Defining a Map

To start using a Map in Mongoose, you first need to define it within your schema:

const mongoose = require('mongoose');
const { Schema } = mongoose;

const userSchema = new Schema({
  dynamicData: {
    type: Map,
    of: String
  }
});

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

In the code above, dynamicData is a Map that stores string values.

Working with Maps

Once you have a map defined, you can interact with it like a regular JavaScript map:

let user = new User();
user.dynamicData.set('key1', 'value1');
user.save();

Here, you’re adding a key-value pair to the Map before saving the user instance.

Asynchronous Operations

Using async/await, you can work with Maps fluently within asynchronous functions:

const createUser = async (key, value) => {
  const user = new User();
  user.dynamicData.set(key, value);
  await user.save();
};

You could call this function to create a new user with dynamic data.

Nested Maps and Subdocuments

In more complex scenarios, Maps can store subdocuments:

const userInfoSchema = new Schema({
  bio: String,
  age: Number
});

const userSchema = new Schema({
  dynamicData: {
    type: Map,
    of: userInfoSchema
  }
});

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

This allows for each key to have a structured value defined by another schema.

Querying Documents with Map Fields

To query documents based on keys in a Map, you use the same dot notation:

const findUserByDynamicKey = async (key) => {
  return User.findOne({[`dynamicData.${key}`]: {$exists: true}}).exec();
};

The function above will find users that have a specific dynamic key.

Validating Maps

Mongoose allows you to add validators to Maps for data integrity:

const userSchema = new Schema({
  dynamicData: {
    type: Map,
    of: {
      type: String,
      validate: /\d+/
    }
  }
});

// The map now only accepts strings that are numerical digits.

Add regular expressions or custom validation functions according to your needs.

Conclusion

This tutorial provided a foundational understanding of using Map schema types within Mongoose, complete with examples from defining Maps to querying and validating them. Leveraging Maps, you can create data structures that are both flexible and powerful, expanding the capabilities of your Mongo database interactions significantly.

Next Article: Understanding Mongoose deleteMany() function (with examples)

Previous Article: How to Use Field Aliases in Mongoose

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates