Connect multiple mongo db database in node js using mongoose - node.js

I am using mongoose for mongo db connections in node js. Can anyone tell me how can I connect multiple databases in node js. Also please make sure that you have tried that method yourself. Thanks.
Edit: I want to connect to multiple DBs dynamically. Also I don't want multiple models and I have just one project, not various sub-projects.

i believe you are connecting to mongoDB from main entrypoint as index.js or server.js , where you are initiating router. like this
`
const mongoose = require('mongoose')
// mongoose
mongoose.connect("mongoDB url");
const connection = mongoose.connection;
connection.on('open',()=>{
console.log(" database connected")
})
connection.on('error',()=>{
console.log("error in connecting to database")
})
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
//middlewares`
in same way you can also connect to different databases directly schemas. like in my use case , i wanted to store users in defferent database and posts in another DB .
the in my app.js , i will connect to main DB as normal connection (above) and for user schema , i will connect to my user DB . like this
const mongoose = require('mongoose');
const connection = mongoose.createConnection("mongo url ");
const userSchema = mongoose.Schema({
name: String,
date_of_birth: Date
})
module.exports = mongoose.model('User', userSchema);
you can also use mongoose.connect() instead of mongoose.createConnection()
hope this helped you.

Related

MongooseError: Operation `users.findOne()` buffering timed out after 10000ms

This is my connection file
const connectDB = async () =>{
const conn = await new mongoose("mongodb+srv://nikunj:gadia7420#cluster0.94xph.mongodb.net/myFirstDatabase?retryWrites=true&w=majority",
{
usenewurlparser:true,
usecreateindex:true,
usefindmodify:true,
useunifiedtropology:true,
urlencoded:true
})
}
module.exports = connectDB;
this is my models file
const userSchema = new mongoose.Schema({
username:{
type:String,
required:true
},
avatar:{
type:String,
},
email:{
type:String,
required:true
},
password:{
type : String,
required:true
}
});
module.exports = mongoose.model('user',userSchema);
this file will insert or take information from database for registeration
const express = require('express');
const router = express.Router();
const User = require('../models/user');
const bcrypt= require('bcrypt');
router.post('/register',async(req,res,next)=>{
const {username,email,password}=req.body;
try{
let user_exist = await User.findOne({email:email});
if(user_exist){
success="false";
msg="user already exist";
} else {
//importing data to models
let user = new User();
user.username = username;
user.email = email ;
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password,salt),
user.avatar = "https://gravatar.com/avatar/?s=200&d=retro"
await user.save();
res.json({
sucess:true,
user:user,
msg:"user registered"
})
}
}
catch(err){
console.log(err);
}
});
module.exports = router;
this is my main file (server.js )
const express = require('express');
const morgan = require('morgan');
const colors = require('colors');
const dotenv = require('dotenv');
const mongoose = require('mongoose');
const connectDB = require('./config/db');
//creating main platform
connectDB;
console.log(mongoose.connection.readyState);
const app = express();
app.use(morgan('dev'));
dotenv.config({
path:'./config/config.env'
})
app.use(express.json({}))
app.use(express.json({
extended:true
}))
//creating server
app.use('/api/todo/auth',require('./routes/user'));
const Port = process.env.port;
app.listen(Port,
console.log(`listening on port :${Port}` .red.underline.bold));
//creating req,res platform
but after running this it shows error while giving post request
MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (D:\nikunj\Programming\todoapp\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:185:20)
at listOnTimeout (node:internal/timers:556:17)
at processTimers (node:internal/timers:499:7)
pls find a solution for this. thanks .sorry if it is a silly or wrong question because I am new to this nodejs
Connect to your database 1st and after that start your server.
You're trying to query the database without connecting to your database.
https://mongoosejs.com/docs/connections.html#buffering
Mongoose lets you start using your models immediately, without waiting for mongoose to establish a connection to MongoDB.
That's because mongoose buffers model function calls internally. This buffering is convenient, but also a common source of confusion. Mongoose will not throw any errors by default if you use a model without connecting.
connectDB()
.then(() -> {
app.listen(Port, console.log(`listening on port :${Port}` .red.underline.bold));
}).catch((e) => {
console.log(e);
})
You're not calling the function connectDB
Turn on your Mongo Server and connect to your database before you attempt to write to it.
In my case I am using a monorepo, one package initiates the server and another contains the mongoose models.
One of the packages had a different mongoose version on it's package.json's dependencies.
The problem was fixed after making sure both packages had the same version of mongoose and then running yarn at the root of the monorepo to relink dependencies properly.
For anyone wondering, I'm able to use mongoose on two different packages in a monorepo since mongoose is basically a singleton class, meaning that it will usually try to use a pre-existing instance of mongoose wherever it is mentioned without initialization.
Having two versions of mongoose breaks this singleton functionality since (as far as Node is concerned) the instance on the server was created using a different mongoose package than the one on my models package.
TL;DR Make sure any packages in your monorepo depending on mongoose have the same version of mongoose in their respective package.json files.
This question has already been answered, however when I encountered with the same problem, the cause was very different. For some reason I put Mongodb connection URI inside quotes in config vars. Never do that. When I removed the quotes, everything worked just fine.
I faced this problem at mongoose v "^6.3.4" and when I removed my IP from network access on sidebar on mongodb and added it again it worked
I faced this problem at mongoose v "^6.3.4" and when I removed my IP
from network access on sidebar on mongodb and added it again it worked
This worked for me too. I removed my ip and selected "ALLOW ACCESS FROM ANYWHERE" option on the network access page and it worked.
(I think it is safe: "Allow access from anywhere" MongoDB Atlas)

Mongoose schema does not work for Mongo Atlas

I am migrating the MongoDB database which is running on my local machine to MongoDB Atlas(a copy of the local DB). I have created a middleware using NodeJS and ExpressJS to get the records from the MongoDB.
To access the MongoDB from my Node application, I am making use of Mongoose. I have defined a schema for the collection.
When I am connecting to the local copy of the MongoDB, all the endpoints work correctly and I get the required results. But as soon as I try to access the DB hosted on Atlas, I do not get any results while using mongoose and the same schema. When I try to retrieve the data using mongodb driver and MongoClient, I get the data but not while using mongoose.
Any idea as to why this might be happening? I have checked the permissions of users and it is correctly configured.
Thanks!
index.js:
const url = "mongodb+srv://<username>:<password>#mumbaicluster.4yone.gcp.mongodb.net/<db>?retryWrites=true";
const connect = mongoose.connect(url,{useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true})
var app = express()
app.use(cors())
const connection = mongoose.connection;
connection.once('open',() => {
console.log("Connected!")
app.use("/",productRouter)
})
app.use(bodyParser.urlencoded({extended: true}))
Removed username, password and DB name.
router.js:
productRouter.route("/").get((req, res, next) => {
Product.find({}).then((products) => {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.send(products);
});
});
I can access the DB using MongoDB Compass

How does mongoose model connect with mongodb?

I have structured a user collection using mongoose.model().This model exist in seperate file called as model\user.js. The mongodb connection instance (using mongoose) exist in seperate file db\mongoose.js. Both of these files are imported into server.js to work with web application.
var express = require('express');
var bodyParser = require('body-parser');
var {mongoose} = require('./db/mongoose');
var {User} = require('./models/user');
var app = express();
app.use(bodyParser.json());
app.post('/todos', (req, res) => {
var user = new User({
text: req.body.text
});
user.save().then((doc) => {
res.send(doc);
}, (e) => {
res.status(400).send(e);
});
});
app.listen(3000, () => {
console.log('Started on port 3000');
});
module.exports = {app};
The {mongoose} and {User} seems to be a separate entities and model\user.js didn't import ./db/mongoose.js as well . The user model being static content , how does user.save() connects with db and save the document?
First of all let me tell you what is happening in your project.
in Mongoose file:
You have DB connection with Mongoose.
Now Mongoose has your DB connection.
That is the reason it is imported in server.js file.
Secondly, in you model/user.js you have
Declared Schema using Mongoose.
user.save method.
When you use Mongoose here (or any DB related query), it points to your connected DB. Which does not require any explicit connection written in some file.
For more details read Mongoose Docs.
Hope I cleared your thoughts.

How to connect node API to specific mongoDB db / collection on my local machine

This has probably been asked before because of how high level the question is, however I couldn't find a solution and am struggling to get this set up. I am working on my first full stack web app using MERN stack. I am on a Mac. Everything I'm doing here is on my local machine.
For MongoDB, I have it installed on my local machine. I have the mongod dameom running. Here's what I have in my interactive mongo shell:
// run in terminal
> mongo
> show dbs
admin 0.000GB
config 0.000GB
mydboverhere 0.064GB
local 0.000GB
> use mydboverhere
switched to db mydboverhere
> show collections
table_one
table_two
andathirdtable
I would like to connect my node/express API to the mydboverhere database. In my node directory structure, I have a models directory with:
/models/index.js
var mongoose = require('mongoose');
mongoose.set('debug', true);
// is this line correct?
mongoose.connect('mongodb://localhost:27017/mydboverhere/table_one');
mongoose.Promise = Promise;
module.exports.Todo = require("./table1"); // this requires table1.js
and /models/table1.js
// this matches the form of the data in the database, I believe
var mongoose = require('mongoose');
var tab1Schema = new mongoose.Schema({
name: {
type: String,
required: 'cannot be blank'
},
completed: {
type: Boolean,
default: false
},
created_date: {
type: Date,
default: Date.now
}
})
var Table1 = mongoose.model('Table1', tab1Schema)
module.exports = Table1;
I believe I have my /routes/tableroutes file correct:
var express = require('express');
var router = express.Router();
var db = require('../models')
router.get('/', function(req, res){
// res.send("Hello from the table1 route")
db.Table1.find()
.then(function(data) {
res.json(data);
})
.catch(function(err) {
res.send(err);
})
});
module.exports = router;
and also I think I am loading these routes into my root /index.js file correctly as well:
var express = require('express')
var app = express();
var tableRoutes = require('./routes/tableroutes');
// test the root route
app.get('/', function(req, res){
res.send("Hello from the Root Route")
});
// set base route to /api for my tableRoutes
app.use('/api', tableRoutes);
app.listen(3000, () => console.log('Example app listening on port 3000!'))
Unfortunately, with mongod running, when I try to run node index.js to get my node app running, I receive the following error message in my command line:
... (node:66245) UnhandledPromiseRejectionWarning: Error: Unsupported host 'localhost:27017/mydboverhere/table_one', hosts must be URL encoded and contain at most one unencoded slash ...
And I'm stuck here right now... pretty much, i'm not sure if Im connecting my node API with mongodb correctly or not. This is all being done on my local machine, and I have mongodb installed at /data/db as it should be. Maybe the error is due to the underscore in the collection name table_one. Maybe the error is because the data in the table_one collection in mongo doesnt' match exactly with the schema in table1.js (I created the mongodb separately by pushing a dataframe from R into it, and then wrote the table1.js schema to match it).
Regardless of which of the following above issues is the issue, I'm not sure, and I'm struggling to continue. Any help here is greatly appreciated!
EDIT1: I have a strong feeling that the following line:
mongoose.connect('mongodb://localhost:27017/mydboverhere/table_one');
is incorrect, and am seeing the proper way to connect to a specific db.
EDIT2: I think there's another javascript library called mongoDB for this, but I would very much prefer to get this working with mongoose.
I think there is an error here:
You are using thisdboverhere whereas it should be mydboverhere.
mongoose.connect('mongodb://localhost:27017/mydboverhere', function(){
// do your process here
});
Or
mongoose.connect('mongodb://localhost:27017/mydboverhere');
var db = mongoose.connection // I think you are forgetting to instantiate the connection here
From this good github post here, I found the following:
Make sure you're connecting to the same database
(mongoose.connect('mongodb://hostname:27017/<db name here>'))
and accessing the same collection
(mongoose.model('<model name>', schema, '<collection name here>'))
I'm late to the party, but I had the same error message. Removing the underscore in the database name fixed it for me.
My original database name I tried was:
const URL_MONGODB = "mongodb://localhost:27017/portfolio_db";
I removed the underscore, and used this database name:
const URL_MONGODB = "mongodb://localhost:27017/portfoliodb";
After which, I no longer got the error "UnhandledPromiseRejectionWarning: Error: Unsupported host 'localhost:27017/data/db', hosts must be URL encoded and contain at most one unencoded slash"

Understanding mongoose connections in express.js

I am learning express.js using the following project:
https://github.com/scotch-io/easy-node-authentication/tree/linking
In server.js I can see and understand the following initiates a connection to the database using the url from database.js:
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
/app/models/user.js contains the following:
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
},
...
}
module.exports = mongoose.model('User', userSchema);
Finally /config/passport.js contains:
var User = require('../app/models/user');
I can see how passport.js obtabs the model from user.js however I am failing to understand how user.js is aware of the connection setup in server.js as the initiated object "mongoose" is not exported?
What am I missing?
as you can see in this file index.js at the last line
var mongoose = module.exports = exports = new Mongoose;
this mean, Mongoosee will export only one instance (singleton) to handler database operations. because you first create connection in your server.js file, after that, any included/require model will have connection to your db server. all app will work on single object.

Resources