People who are used to building apps with Mongo and Nodejs should be familiar with Mongoose which is an ORM for MongoDB. Though there are other competitive ORMs available, it is one of the most popular and efficient ORMs for Mongo connectivity. When I build my applications, my first choice would be to use a Mongo database. The main reason is that I have used it on many apps and find it comfortable to use.
I recently had a requirement to establish connections and work on multiple Mongo databases within my backend application. More like switching between multiple databases based on user requests. There were a few solutions that I came across online and finally fixed with a solution.
- Have multiple connection strings saved in the config file and switch between them or connect to each one of them. This can work if we are working only on a few databases.
- Opening and closing connections for every request.
- Have a single connection to a master database and switch to other databases internally using useDb feature.
I solved my need with the third solution. In my case, I was using models and I wanted them to be common for all the databases. That's why I came up with this solution and it works well. I'm going to walk through the code step by step.
Note: I'm assuming that the readers are familiar with Nodejs and MongoDB. I'm not going to be covering the complete code of the backend application.
Step 1: Creating the db.js file
This file will have basic connection information to the database. I usually keep this file separately and establish the connection only by including this file in my main file. It helps in modularizing the code.
const mongoose = require('mongoose');
const database = 'mongodb://localhost:27017/primary';
mongoose.connect(database, {});
const db = mongoose.connection;
// Check DB Connection
db.once('open', () => {
// eslint-disable-next-line no-console
console.log('Connected to MongoDB');
});
// Check for DB errors
db.on('error', (err) => {
// eslint-disable-next-line no-console
console.log('DB Connection errors', err);
});
module.exports = mongoose;
If you notice I would have primary
as my database. This is the primary database that I would be connecting to. Only from that database, I would be switching to other databases whenever needed.
Step 2: Creating my model file client.js
The next step would be to create my model file that will have the schema of my collection. I wanted to have a single model file created for a collection that I would be using across all the databases.
const mongoose = require('mongoose');
// eslint-disable-next-line prefer-destructuring
const Schema = mongoose.Schema;
const clientSchema = new Schema(
{
clientNumber: {
type: Number,
required: true,
},
clientName: {
type: String,
required: true,
},
},
{ versionKey: false, minimize: false },
);
const client = async (db) => {
const myDB = mongoose.connection.useDb(db);
const Client = myDB.model('Client',clientSchema);
return Client;
};
module.exports = { client };
In the above model file, I have a schema for the Client with two fields in that. If you look at the code, I have a function towards the end of the code that accepts the database as the input parameter and gives the model as the output parameter.
Step 3: My main.js file
In my main.js file, I have the below code to create a new client. I have included both of the above files in this main file. I wanted to test it out by creating a client on multiple databases at the same time.
require('./db');
const { client } = require('./client');
// Saving to primary database
(async () => {
const Client = await client('primary');
const c = new Client();
c.clientNumber = 1234;
c.clientName = 'Test Client';
await c.save();
})();
// Saving to secondary1 database
(async () => {
const Client = await client('secondary1');
const c = new Client();
c.clientNumber = 1234;
c.clientName = 'Test Client';
await c.save();
})();
// Saving to secondary2 database
(async () => {
const Client = await client('secondary2');
const c = new Client();
c.clientNumber = 1234;
c.clientName = 'Test Client';
await c.save();
})();
As we all know Nodejs is asynchronous by default, when we execute the main.js file, it executes all the 3 functions at the same time creating the same entry on 3 different databases. This is an example to show how we can pass the database name as a parameter to the model and perform operations on specific models in each database.
If you like what I'm doing on Hive, you can vote me as a witness with the links below.
|
|
|
|
|
|