Guide to connect to multiple databases using Mongoose

in #hive-1693218 months ago

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.

image.png

Source

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.

Vote @balaz as a Hive Witness

Vote @kanibot as a Hive Engine Witness



Sort:  

Well detailed and thank you for sharing this. It will really help to open a lot of people eyes to see this

Congratulations @balaz! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You received more than 1000 HP as payout for your posts, comments and curation.
Your next payout target is 2000 HP.
The unit is Hive Power equivalent because post and comment rewards can be split into HP and HBD

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Wow it quite looks a bit complicated for me or probably I have little understanding of how these things actually works though

This seem hard, lol but thanks very much for the lecture
It was a good one

Mongo has seen quite decent adaptation. It fits well with needs of all scale of projects and provides flexibility to work with complex data structures. Good to see blogs on programing, very well explained. keep posting.

This post has been manually curated by @bhattg from Indiaunited community. Join us on our Discord Server.

Do you know that you can earn a passive income by delegating to @indiaunited. We share more than 100 % of the curation rewards with the delegators in the form of IUC tokens. HP delegators and IUC token holders also get upto 20% additional vote weight.

Here are some handy links for delegations: 100HP, 250HP, 500HP, 1000HP.

image.png

100% of the rewards from this comment goes to the curator for their manual curation efforts. Please encourage the curator @bhattg by upvoting this comment and support the community by voting the posts made by @indiaunited.