Print the names of collections with mongoDB and node.js - node.js

im using mongoclient and im sure that I have connection to the database
const client = new MongoClient(uri);
const datatbaseslist = client.db().admin().listDatabases();
datatbaseslist.databases.forEach(db => {
console.log($db.name)
});
I saw that code in a video of the mongodb and its not working.
thanks
I have tried looking for other versions to that line
const datatbaseslist = client.db().admin().listDatabases();
datatbaseslist.databases.forEach(db => {
console.log($db.name)
});
because im pretty sure that the problem is there.

I think your question title is saying one thing (collections) and your code is confusing this any another (databases).
A mongodb server can have multiple databases.
A database can have multiple collections.
You connect to the server using a client.
Normally if you want to know about the databases, you would use admin(). Or to connect to a specific database (although you can connect via URI), the you use db(dbName) from the client.
Once you have a db object, you can get the collections from there.
The below code shows you how to get both databases and collections.
const { MongoClient } = require('mongodb')
async function main () {
// Set config
const uri = 'mongodb://localhost:27017'
const client = new MongoClient(uri)
try {
// Connect to the MongoDB cluster
await client.connect()
// Get databases
const databasesList = await client.db().admin().listDatabases()
for (const dbName of databasesList.databases.map(db => db.name)) {
console.log('DB: ', dbName)
// Get collections for each database
const collections = await client.db(dbName).listCollections().toArray()
console.log('Collections:', collections.map(col => col.name).join(', '))
console.log('---------------------------------------------')
}
} catch (e) {
// Handle any erros
console.error(e)
} finally {
// Always close the connection to the database when finished
await client.close()
}
}
main().catch(console.error)

Related

Mongodb native connections from nodejs return undefined databases list

I'm just starting to use Mongodb without mongoose (to get away from the schemas), and wanted to create a simple module with various exported functions to use in the rest of my app. I've pasted the code below.
The problem I'm having is that the databasesList.databases comes back as undefined, and I'm not sure why. There should be 2 databases on my cluster, and one collection in each database.
As a tangential question, I thought maybe I would check the collections instead (now commented out), but though I found this page (https://docs.mongodb.com/manual/reference/method/db.getCollectionNames/) the function getCollectionNames seems not to exist. Now I'm wondering if I'm using the wrong documentation and that is why my databases are coming back undefined.
const client = new MongoClient(uri)
const connection = client.connect( function (err, database) {
if (err) throw err;
else if (!database) console.log('Unknown error connecting to database');
else {
console.log('Connected to MongoDB database server');
}
});
module.exports = {
getDatabaseList: function() {
console.log('start ' + client);
databasesList = client.db().admin().listDatabases();
//collectionList = client.db().getCollectionNames();
//console.log("Collections: " + collectionList);
console.log("Databases: " + databasesList.databases);
//databasesList.databases.forEach(db => console.log(` - ${db.name}`));
}
}```
your code is correct Just need to change few things.
module.exports = {
getDatabaseList: async function() {
console.log('start ' + client);
databasesList = await client.db().admin().listDatabases();
//collectionList = await client.db().getCollectionNames();
//console.log("Collections: " + collectionList);
console.log("Databases: " + databasesList.databases);
databasesList.databases.forEach(db => console.log(` - ${db.name}`));
}
}
You have to declare async function and use await also.
The async and await keywords enable asynchronous, promise-based behaviour to be written in a cleaner style, avoiding the need to explicitly configure promise chains.
You can use this modular approach to build your database access code:
index.js: Run your database application code, like list database names, collection names and read from a collection.
const connect = require('./database');
const dbFunctions = require('./dbFunctions');
const start = async function() {
const connection = await connect();
console.log('Connected...');
const dbNames = await dbFunctions.getDbNames(connection);
console.log(await dbNames.databases.map(e => e.name));
const colls = await dbFunctions.getCollNames(connection, 'test');
console.log(await colls.map(e => e.name));
console.log(await dbFunctions.getDocs(connection, 'test', 'test'));
};
start();
database.js:: Create a connection object. This connection is used for all your database access code. In general, a single connection creates a connection pool and this can be used throughout a small application
const { MongoClient } = require('mongodb');
const url = 'mongodb://localhost:27017/';
const opts = { useUnifiedTopology: true };
async function connect() {
console.log('Connecting to db server...');
return await MongoClient.connect(url, opts );
}
module.exports = connect;
dbFunctions.js:: Various functions to access database details, collection details and query a specific collection.
module.exports = {
// return list of database names
getDbNames: async function(conn) {
return await conn.db().admin().listDatabases( { nameOnly: true } );
},
// return collections list as an array for a given database
getCollNames: async function(conn, db) {
return await conn.db(db).listCollections().toArray();
},
// return documents as an array for a given database and collection
getDocs: async function(conn, db, coll) {
return await conn.db(db).collection(coll).find().toArray();
}
}

Need help connecting and inserting data to mongodb

I need some help with mongodb.
I just started using it, and made a Cluster called db, with a database called discord-bot with a collection called users
This should make a database entry for every user, so here is my code
const { MongoClient } = require("mongodb");
const uri = "mongodb+srv://<My username>:<My password>#<My db url>?retryWrites=true&w=majority";
const client = new MongoClient(uri);
async function run(query) {
try {
await client.connect();
const database = client.db('discord-bot');
const collection = database.collection('users');
await collection.insertOne(query);
} finally {
await client.close();
}
}
botClient.users.cache.forEach(u => {
const q = { name: u.username }
run(q).catch(console.dir);
})
I think this code should work, but it is giving me this error
TypeError: Cannot read property 'maxWireVersion' of null
I can not find anything online about that error, can somebody help me figure out what that error is and how to fix it. (Also, i am using mongodb with discord.js, incase that is neccessary info)
I use this to connect to mongo DB
const MongoClient = require('mongodb').MongoClient;
var connection;
MongoClient.connect('your-db-uri', { useUnifiedTopology: true }, async function(err, client) {
if(err)throw err
console.log("Successfully Connected")
connection = client
})
Then you can use connection variable as global for all functions

Should I open/close database connection after every query/insert?

Hey everyone i'm developer a simple app in last days using nodejs and create this function to return client instance from mongodb
const mongodb = require("mongodb");
const { db } = require("../config/env");
const conection = async () => {
try {
const client = await mongodb.MongoClient.connect(db.uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
return client;
} catch (error) {
throw error;
}
};
module.exports = conection;
and i make this simple function for acess data layer and return records instered
const index = async ({ limit = 10, offset = 0, filter = {} }) => {
const client = await conection();
if (filter._id) {
filter._id = mongodb.ObjectID(filter._id);
}
try {
const collection = client.db("api").collection("user");
const data = await collection
.find({ ...filter })
.skip(offset)
.limit(limit)
.toArray();
return data;
} catch (error) {
throw new Error(error);
} finally {
await client.close();
}
};
I would like to know if I really need to make the connection and close it with each query or should I keep the connection open
NOTE: in this case I am using a simple Atlas cluster (free) but I would like to know if I should do this also when working with sql banks like postgres
Don't close your connection unless you are exiting your app, and then make sure you do. Ensure that you are using the same connection when you come back to do more I/O. Database connections are resource-intensive and should be established as few times as possible and shared as much as possible. You can also get middleware problems with connections like ODBC if you don't pick up existing connections and get weird errors like connection pools running out. Get to know your connector and how to use it most effectively, it will be a rewarding activity :-)
You can use the mongoose module for managing MongoDB.
Installation
npm install mongoose
Usage
mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true });
I am sure that Mongoose can help you solve your issues.
It's a good practice to do so. so that after every operation(insert etc) you close the connection and before every operation(insert etc) you reopen the connection.

Why can't I see my Mongodb collection inside my app?

Brand new to mongodb, but I think there must be something very fundamental I'm not getting. If I run the shell and type db.questions.count() I get 1,the 1 I created in the shell. But if I do the same thing in my app:
...
const MONGO_URL = 'mongodb://127.0.0.1:27017/';
const {MongoClient, ObjectId} = mongo;
const run = async () => {
try {
const db = await
MongoClient.connect(MONGO_URL);
const Questions = db.questions;
console.log(Questions.count());
...
I get Cannot read property 'count' of undefined. Why is this?
For what it's worth, db is defined, and the URL is the same one from the shell. Plus the server starts fine, so I assume that means the mongodb instance is running fine.
Install the "mongodb" npm module. It is the official MongoDB client for NodeJs.
// Create a Mongo Client Instace to connect to the MongoDB Database
// and perform various functions.
const MongoClient = require( 'mongodb' ).MongoClient;
// Store the URL of your MongoDB Server
const mongoURL = "mongodb://localhost:27017/";
// Stored the name of the Database you wanna connect to.
const dbName = "testdb";
// Create a new Mongo DB client that will connect to the MongoDB Server.
const client = new MongoClient(mongoURL);
// Connect the Client to the MongoDB Server.
client.connect( (err) => {
// Error handling of some sort.
if(err) throw err;
console.log( 'connected!' );
// Connect to the database you want to manage using the dbName you
// stored earlier.
const db = client.db( dbName );
// Store the name of the collection you want to read from.
// this can be created above near the dbName.
const collectionName = "testCol"
// Connect to the collection that you stored above.
const collection = db.collection( collectionName );
// Query the MongoDB database and log the results, if any.
collection.find({}).toArray( (err, docs) => {
console.log(docs);
} );
} )
To get rid of that newURLParser error, just use
const client = new MongoClient( mongoURL, { useNewUrlParser: true } );
instead of
const client = new MongoClient(mongoURL);
Here's the link to MongoDB NodeJS quickstart.
http://mongodb.github.io/node-mongodb-native/3.1/quick-start/quick-start/

switching database with mongoose

Hi is there a way to switch database with mongoose?
I thought I could do it like that:
mongoose.disconnect();
mongoose.connect('localhost',db);
but it does not work I receive this error:
Error: Trying to open unclosed connection.
I do not know if it is because is asynchronous
As already stated you could do it using useDb function :
Example code :
async function myDbConnection() {
const url = 'mongodb+srv://username:password#cluster0-pauvx.mongodb.net/test?retryWrites=true&w=majority';
try {
await mongoose.connect(url, { useNewUrlParser: true });
console.log('Connected Successfully')
// Here from above url you've already got connected to test DB,
So let's make a switch as needed.
mongoose.connection.useDb('myDB'); // Switching happens here..
/**
* Do some DB transaction with mongoose models as by now models has already been registered to created DB connection
*/
} catch (error) {
console.log('Error connecting to DB ::', error);
}
}
Or if you wanted to create a complete new connection then you've to try mongoose.createConnection(). Just for reference in case of mongoDB driver you would use ::
mongodb.MongoClient.connect(mongourl, function(err, primaryDB) {
// open another database over the same connection
const secondaryDB = primaryDB.db(SECONDARY_DATABASE_NAME);
// now you can use both `database` and `database2`
...
});
Ref : mongoose multiple different connections, mongoose useDb(), mongoDB driver switch connections
It is asynchronous. If you pass a callback function to disconnect and try to connect to the next database in that callback, it will work.
Ex.
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/test1', function() {
console.log('Connected to test 1')
mongoose.disconnect(connectToTest2)
})
function connectToTest2() {
mongoose.connect('mongodb://localhost/test2', function() {
console.log('Connected to test 2')
process.exit()
})
}
The top-voted answer had thrown me in a loop for a few hours. To help the OP and others who may have the same issue, here's my take on the solution:
Suppose you have two databases with the same schema and you want to switch between them on the fly. Let's call them DB1 and DB2. Here's how you can go about doing that:
(async () => {
const connection = await mongoose.createConnection(url, options);
const getModel = (database) => {
const dbConnection = connection.useDb(database);
return dbConnection.model('Model', modelSchema);
};
const Db1Model = getModel('DB1');
const Db2Model = getModel('DB2');
})();
Tested on Node.js v12 and Mongoose v5.
One way you can achieve this is by appending the database name with the database URL. For eg: if you are working with localhost
mongoose.connect('mongodb://localhost:portNumber/xyz_db');
When you connect like this, all your models will be saved in the xyz_db under your model as a collection.
You should use the useDb function like so:
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.connection.useDb('Users'); # Change the string to the name of the database you want to use

Resources