Node.js
Mongoose
multiple databases
database management
backend development

Mongoose and multiple database in single node.js project

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Mongoose is a powerful Object Data Modeling (ODM) library for MongoDB and Node.js. It provides a straight-forward, schema-based solution to model application data. By abstracting interactions with the MongoDB database, Mongoose enables developers to handle complex data relationships, along with schemas, models, and validation with ease.

In larger applications, a single database connection might not suffice due to scalability considerations, multiple types of data stores, or different service configurations. Consequently, setting up multiple databases in a single Node.js project using Mongoose becomes necessary.

This article delves into integrating Mongoose with multiple databases, explaining the technical steps involved, complete with examples and relevant additional subtopics.

Understanding the Basics

Before diving into multiple databases, let's briefly recall how to connect a Node.js application to a single MongoDB database using Mongoose:

javascript
1const mongoose = require('mongoose');
2
3// Connect to a single MongoDB database
4mongoose.connect('mongodb://localhost:27017/myapp', {
5  useNewUrlParser: true,
6  useUnifiedTopology: true
7});
8
9const db = mongoose.connection;
10db.on('error', console.error.bind(console, 'connection error:'));
11db.once('open', function() {
12  console.log('Connected to the database');
13});

The code connects to a MongoDB database located at "localhost" on port 27017 using the myapp database name. However, in multi-database configurations, we must go beyond this basic setup.

Multiple Databases in a Single Node.js Project

There are situations where we might want to use different databases within the same application. For instance, one database could store application data while another could store logging or user data. Mongoose facilitates this separation through multiple connections.

Setting Up Multiple Connections

To handle multiple database connections, you need to create separate connection instances. Here's an example of how you can connect to two different databases:

javascript
1const mongoose = require('mongoose');
2
3// Connect to the first MongoDB instance
4const connection1 = mongoose.createConnection('mongodb://localhost:27017/appdata', {
5  useNewUrlParser: true,
6  useUnifiedTopology: true
7});
8
9// Connect to the second MongoDB instance
10const connection2 = mongoose.createConnection('mongodb://localhost:27017/logs', {
11  useNewUrlParser: true,
12  useUnifiedTopology: true
13});
14
15// Handle connection events
16connection1.on('connected', () => console.log('Connected to appdata database'));
17connection2.on('connected', () => console.log('Connected to logs database'));

Defining Models for Each Database

Models are defined per connection when using multiple databases. You cannot use the mongoose.model() method directly as it assumes the default connection. Instead, use the model() method of each connection instance:

javascript
1// Define a schema
2const userSchema = new mongoose.Schema({
3  name: String,
4  email: String
5});
6
7// Define a schema for logs
8const logSchema = new mongoose.Schema({
9  message: String,
10  timestamp: { type: Date, default: Date.now }
11});
12
13// Create models on respective connections
14const User = connection1.model('User', userSchema);
15const Log = connection2.model('Log', logSchema);

Querying Across Databases

Once the connections and models are set, executing queries involves calling the model methods:

javascript
1// Inserting a new user in the appdata database
2const newUser = new User({ name: 'John Doe', email: '[email protected]' });
3newUser.save()
4  .then(() => console.log('User saved'))
5  .catch(err => console.log('User save error:', err));
6
7// Inserting a new log in the logs database
8const newLog = new Log({ message: 'User registered' });
9newLog.save()
10  .then(() => console.log('Log saved'))
11  .catch(err => console.log('Log save error:', err));

Each query is executed against the respective database configured for the model.

Considerations

Performance and Load

Handling multiple databases within a single Node.js application can potentially impact performance. Depending on the workloads and database sizes, you might consider optimizing connections or spreading them across multiple servers.

Connection Pooling

Mongoose allows configuring a pool of connections, which can be especially useful when operating at scale:

javascript
1// Examples for setting max poolSize for a connection
2const connectionOptions = {
3  useNewUrlParser: true,
4  useUnifiedTopology: true,
5  poolSize: 10 // Maintain up to 10 socket connections
6};
7
8const connection1 = mongoose.createConnection('mongodb://localhost:27017/appdata', connectionOptions);
9const connection2 = mongoose.createConnection('mongodb://localhost:27017/logs', connectionOptions);

Error Handling

Robust error handling is essential when dealing with numerous databases. Monitoring and logging errors across connections help maintain stability.

Summary Table

Here is a brief summary contrasting single vs. multiple database setups:

AspectSingle DatabaseMultiple Databases
ConnectionOne default connection in MongooseIndependent createConnection() per database
Model DefinitionGlobal with mongoose.model()Local with model() on each connection
ComplexitySimpler setupRequires additional management
Use CaseSmaller applicationsLarger scale, different types of data
PerformanceLimited by a single connectionPotentially scalable with separate databases

Conclusion

Integrating multiple databases within a single Node.js project using Mongoose enables enhanced flexibility and scalability for applications. This approach is particularly suitable for larger applications needing to differentiate between various kinds of data or environments. Understanding how connections and models operate within this context is vital for effectively managing and querying your datasets. With the appropriate setup and considerations for performance and error handling, applications can be robust and adequately prepared for extensive operations.


Course illustration
Course illustration

All Rights Reserved.