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

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)

Related

Get existing document from MongoDB with Mongoose

I have an existing document on MongoDB atlas that I need to get in its entirety. When I try my current code I get a socket timeout, i.e. it keeps buffering.
There is only one document in my collection.
My theory is that the error is in my Mongoose Schema, but I don't know what to put there since I don't want any "filters", I want everything.
The name of the collection in Atlas is Playstation and the id of the document I want to get is: 5f5e2d281386efc27bb3ce45
const express = require('express')
const router = express.Router()
const Playstation = require('../models/playstation')
//Getting All
router.get('/', async (req, res) => {
try {
const playstations = await Playstation.findById("5f5e2d281386efc27bb3ce45")
res.json(playstations)
} catch (err) {
res.status(500).json({ message: err.message })
}
})
module.exports = router;
My schema & model:
const mongoose = require('mongoose')
const playstationSchema = new mongoose.Schema({
})
module.exports = mongoose.model('Playstation', playstationSchema)
I believe the problem is your mongoose schema. What you want is a schemaless collection, since you dont want to define the schema, and you want everything in the document, you can define the collection as schema-less, with strict:false option in your mongoose schema;
Try this:
const mongoose = require('mongoose')
const playstationSchema = new mongoose.Schema({
},{ strict : false })
module.exports = mongoose.model('Playstation', playstationSchema);
You can read more about this option on Mongoose Documentation

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"

Mongoose MongoDB in Production

I'm having a really weird issue where Mongoose will not perform queries against collections outside of the Model definition file when NODE_ENV=production, even when connecting to localhost.
db/default.js
const mongoose = require('mongoose');
module.exports = {
connect(url) {
mongoose.connect(url);
}
};
app.js
const db = require('./db/default');
db.connect(config.get('mongoDB.uri'));
User.model.js
const mongoose = require('mongoose');
const schema = new mongoose.Schema({
// ...
});
const User = mongoose.model('User', schema);
module.exports = User;
test.js
// This file is required by a route
const User = require('./models/User.model');
User.find({})
.then(response => console.log(response))
.catch(err => console.log(err));
All of this works absolutely fine when NODE_ENV=dev, but as soon as NODE_ENV=production, the User.find({})... doesn't run. No errors, no success, it just doesn't run.
If I log the User = require('./models/User.model'), it is a Mongoose object.
If I run the User.find({})... code inside the User.model.js file whilst in production, that also works.
I am utterly befuddled as to why this does not work.

Connect multiple mongo db database in node js using mongoose

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.

Resources