I'm trying to connect to a Mongodb database. But I'm getting no errors just out put as far as,
console.log("001");
dotenv = require('dotenv');
dotenv.config();
const mongodb = require('mongodb').MongoClient;
const { MongoClient } = require("mongodb");
console.log("002");
const uri = process.env.CONNECTIONSTRING;
const client = new MongoClient(uri);
console.log("003");
async function run() {
try{
console.log("004");
client.connect();
//const db = client.db("blah");
console.log("005");
const results = await db.collection("student").find()
console.log("006")
console.log(results)
console.log("007")
client.close()
console.log("hello");
}
catch
{
}
}
//call function
run();
console.log("005");
But not,
console.log("006");
So there must be a problem with line 20,
const results = await db.collection("student").find()
Is the syntax correct here?
Not getting an error and yet it doesn't read any information from the database.
shane#XPS:~/mongostack$ node index.js
001
002
003
004
005
Thanks,
Related
I want to connect to a mongodb database at cloud.mongodb.com using node.
I get the error mongodb.Connect is not a function. What am I doing wrong here?
const dotenv = require("dotenv");
dotenv.config();
const mongodb = require("mongodb");
const connectString = "my connection string";
mongodb.Connect(process.env.CONNECTIONSTRING, async function (err, client) {
const db = client.db();
const results = await db.collection("pets").find().toArray();
console.log(results);
});
JavaScript is case-sensitive. The function is connect, with a lower-case "c":
mongodb.connect(process.env.CONNECTIONSTRING, async function (err, client) {
// ---^
const db = client.db();
const results = await db.collection("pets").find().toArray();
console.log(results);
});
I believe this is due to one or both of these reasons:
You should import MongoClient and not the entire mongodb module
const { MongoClient } = require("mongodb");
The method name is connect and not Connect
I am using serverless on aws with nodejs and mongodb atlas as database
At the moment I am using the trial version which allow maximum 500 connections.
Seems that my code is not disconnecting the database when process end
I am using express to manage it
First I had no connection close thinking that the connection will be closed automatically once the process end but no I had a lot of connections open.
Then I added a middleware to close my connections after the response has been sent, it was not working, I was thinking that serverless was stopping the process once the response was sent.
Not on each route I am closing mongo connection, for example
router.get('/website/:id/page', async (req, res, next) => {
try {
const pages = await pageDataProvider.findByWebsite(req.params.id);
await mongodbDataProvider.close();
res.json(pages);
} catch (error) {
next(error)
}
})
This is how I handle connections with mongo
const MongoClient = require('mongodb').MongoClient
const config = require('../config')
const MONGODB_URI = config.stage === 'test' ?
global.__MONGO_URI__ :
`mongodb+srv://${config.mongodb.username}:${config.mongodb.password}#${config.mongodb.host}/admin?retryWrites=true&w=majority`;
const client = new MongoClient(MONGODB_URI);
let cachedDb = null;
module.exports.connect = async () => {
if (cachedDb) return cachedDb;
await client.connect();
const dbName = config.stage === 'test' ? global.__MONGO_DB_NAME__ : config.stage;
const db = client.db(dbName)
cachedDb = db;
return db;
}
module.exports.close = async () => {
if (!cachedDb) return;
await client.close();
cachedDb = null;
}
I do not understand why I have so many connections open
Step 1
Isolate the call to the MongoClient.connect() function into its own module so that the connections can be reused across functions. Let's create a file mongo-client.js for that:
mongo-client.js:
const { MongoClient } = require('mongodb');
// Export a module-scoped MongoClient promise. By doing this in a separate
// module, the client can be shared across functions.
const client = new MongoClient(process.env.MONGODB_URI);
module.exports = client.connect();
Step 2
Import the new module and use it in function handlers to connect to database.
some-file.js:
const clientPromise = require('./mongodb-client');
// Handler
module.exports.handler = async function(event, context) {
// Get the MongoClient by calling await on the connection promise. Because
// this is a promise, it will only resolve once.
const client = await clientPromise;
// Use the connection to return the name of the connected database for example.
return client.db().databaseName;
}
I think its a programmatic error in your close method. Please have a closer look at
if (!cachedDb) return;
I think it should have been
if (cachedDb != null) return;
As stated in other response, I would strongly advice against closing the DB connections with each request. You should be looking for a pool mechanism, where a connection from the pool is handed to your application. The application can wait till it receives the connection
Closure of the DB connections should be handled at the time when the application is exiting (shutting/going down). This way application will at least try to close the connections gracefully.
Nonetheless, here is an adaptation your program
index.js
const express = require('express')
const app = express()
const port = 3000
const dbProvider = require('./dbProvider');
dbProvider.connect();
app.get('/testConnection',async (req, res, next) => {
console.log('Doing something for fetching the request & closing connection');
dbProvider.close();
console.log('After closing the connection');
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
dbProvider.js
let cachedDb = null;
let db = {};
module.exports.connect = async () => {
if (cachedDb) {
console.log('Returning Cachedb');
return cachedDb;
}
else{
console.log('Not a cachedDB');
}
db.setup = 1;
return db;
}
module.exports.close = async () => {
if (!cachedDb) {
console.log('Since its cached DB not closing the connection');
return;
}
db=null;
return;
}
And here is the console output:
-> node index.js
Not a cachedDB
Example app listening at http://localhost:3000
Doing something for fetching the request & closing connection
Since its cached DB not closing the connection
After closing the connection
According to this: https://docs.atlas.mongodb.com/best-practices-connecting-from-aws-lambda/
It's a good idea to add this line so you keep your connection pool between requests.
context.callbackWaitsForEmptyEventLoop = false;
I'm new to programming, I'm trying to follow a web developemnt course when connecting to database I created I get the error "mongodb.connect is not a function".
I try to connect to the database using the following code.
let mongodb = require('mongodb');
let db
let connectionString = '';
mongodb.connect(connectionString,{useNewUrlParser: true, useUnifiedTopology:
true},function(err, client){
db = client.db();
You can connect to the database from the client (which uses MongoClient from the library).
const { MongoClient } = require('mongodb');
let db;
const connectionString = 'mongodb://' // Change this to your uri
const client = new MongoClient(connectionString)
Then you can connect
await client.connect();
db = client.db();
Try this:
const { MongoClient } = require("mongodb");
let databaseName = '';
let connectionString = '';
MongoClient.connect(connectionString, {useNewUrlParser: true, useUnifiedTopology: true}, (error, client) => {
if (error)
return console.log("Connection failed for some reason");
const db = client.db(databaseName);
});
just try this one
let mongodb = require('mongodb').MongoClient;
this could be for the version of mongodb you are using instead of version used in the course.
I'm kinda new to module creation and was wondering about module.exports and waiting for async functions (like a mongo connect function for example) to complete and exporting the result. The variables get properly defined using async/await in the module, but when trying to log them by requiring the module, they show up as undefined. If someone could point me in the right direction, that'd be great. Here's the code I've got so far:
// module.js
const MongoClient = require('mongodb').MongoClient
const mongo_host = '127.0.0.1'
const mongo_db = 'test'
const mongo_port = '27017';
(async module => {
var client, db
var url = `mongodb://${mongo_host}:${mongo_port}/${mongo_db}`
try {
// Use connect method to connect to the Server
client = await MongoClient.connect(url, {
useNewUrlParser: true
})
db = client.db(mongo_db)
} catch (err) {
console.error(err)
} finally {
// Exporting mongo just to test things
console.log(client) // Just to test things I tried logging the client here and it works. It doesn't show 'undefined' like test.js does when trying to console.log it from there
module.exports = {
client,
db
}
}
})(module)
And here's the js that requires the module
// test.js
const {client} = require('./module')
console.log(client) // Logs 'undefined'
I'm fairly familiar with js and am still actively learning and looking into things like async/await and like features, but yeah... I can't really figure that one out
You have to export synchronously, so its impossible to export client and db directly. However you could export a Promise that resolves to client and db:
module.exports = (async function() {
const client = await MongoClient.connect(url, {
useNewUrlParser: true
});
const db = client.db(mongo_db);
return { client, db };
})();
So then you can import it as:
const {client, db} = await require("yourmodule");
(that has to be in an async function itself)
PS: console.error(err) is not a proper error handler, if you cant handle the error just crash
the solution provided above by #Jonas Wilms is working but requires to call requires in an async function each time we want to reuse the connection. an alternative way is to use a callback function to return the mongoDB client object.
mongo.js:
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<user>:<pwd>#<host and port>?retryWrites=true";
const mongoClient = async function(cb) {
const client = await MongoClient.connect(uri, {
useNewUrlParser: true
});
cb(client);
};
module.exports = {mongoClient}
then we can use mongoClient method in a diffrent file(express route or any other js file).
app.js:
var client;
const mongo = require('path to mongo.js');
mongo.mongoClient((connection) => {
client = connection;
});
//declare express app and listen....
//simple post reuest to store a student..
app.post('/', async (req, res, next) => {
const newStudent = {
name: req.body.name,
description: req.body.description,
studentId: req.body.studetId,
image: req.body.image
};
try
{
await client.db('university').collection('students').insertOne({newStudent});
}
catch(err)
{
console.log(err);
return res.status(500).json({ error: err});
}
return res.status(201).json({ message: 'Student added'});
};
[nodemon] starting node server.js
C:\Users\Abhay\Desktop\todo-app\node_modules\mongodb\lib\utils.js:725
throw error;
^
TypeError: Cannot read property 'db' of undefined
at C:\Users\Abhay\Desktop\todo-app\server.js:8:17
at C:\Users\Abhay\Desktop\todo-app\node_modules\mongodb\lib\utils.js:722:9
at C:\Users\Abhay\Desktop\todo-app\node_modules\mongodb\lib\mongo_client.js:223:23
at C:\Users\Abhay\Desktop\todo-app\node_modules\mongodb\lib\operations\connect.js:279:21
at QueryReqWrap.callback (C:\Users\Abhay\Desktop\todo-app\node_modules\mongodb\lib\core\uri_parser.js:56:21)
at QueryReqWrap.onresolve [as oncomplete] (dns.js:202:10)
[nodemon] app crashed - waiting for file changes before starting...
let express = require('express')
let mongodb = require('mongodb')
let app = express()
let db
let connectionString = 'mongodb+srv://todoAppUser:kTL7PYesKzfB6FMz#cluster0.fif5n.mongodb.net/TodoApp?retryWrites=true&w=majority'
mongodb.connect(connectionString, {useNewUrlParser: true, useUnifiedTopology: true}, function(err, client) {
db = client.db()
app.listen(3000)
})
It seems you're trying to use the static connect method of MongoClient to make a connection to your db, but you are not using the MongoClient class itself.
To connect to any db, you will need a connected instance of MongoClient. Using the static connect method, you can achieve it in the following way:
const mongodb = require("mongodb");
const connectionURL = "mongodb+srv://your-connection-srv-here"
const dbName = "your_db_name"
//get MongoClient
const MongoClient = mongodb.MongoClient;
let db = null;
MongoClient.connect(connectionURL,{
useNewUrlParser: true,
useUnifiedTopology: true
},(err,connectedClient) => {
if(err){
throw err;
}
//connectedClient will be the connected instance of MongoClient
db = connectedClient.db(dbName);
//now you can write queries
db.collection("your_collection").find({}).toArray()
.then(r => {
console.log(r);
}).catch(e => {
console.error(`ERROR:`,e);
})
})
However, using callbacks will be quite cumbersome. As per the docs linked above, most functions in the MongoDb driver for Node.js will return a promise if a callback function is not passed, which is very convenient. Using this, you can write a function which return a promise that resolves a connected instance to your db.
const MongoClient = require('mongodb').MongoClient;
/*
we draw the connection srv and the db name from the config to return just one instance of that db.
Now this function call be called wherever a connection is needed
*/
const getDbInstance = (config) => new Promise((resolve,reject) => {
const client = new MongoClient(config.dbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true
});
client.connect((error) => {
if(error){
console.error(error);
reject(error);
}
let db = client.db(config.dbName);
resolve(db);
})
})
const doSomeDbOperations = async() => {
//hardcoding it here, but this config will probably come from environment variables in your project
const config = {
dbUrl: "mongodb+srv://your-connection-srv-here",
dbName: "your_db_name"
};
try{
const db = await getDbInstance(config);
//do whatever querying you wish here
}catch(e){
console.error(`ERROR: `,e);
}
}
doSomeDbOperations();