How to delete a database using node.js and MongoDB Atlas? - node.js

I'm new to MongoDB and node.js and I want to know how to delete a database.
I've searched for and I found that it is done with the dropDatabase() method. The problem is that it shows a MongoError: user is not allowed to do action [dropDatabase] on [test.]. I also searched for this error and the answer I found is that the user needs to be registered as Data Access Read Write. However, my user in mongo atlas is registred as Project Owner and as the answer says. I removed Project Owner and it still displays the error.
MongoClient.connect(uri, { useNewUrlParser: true }, (err, client)=>{
if(err) throw err;
console.log("Connected...");
const db = client.db("test");
db.dropDatabase();
console.log("asdfghj")
client.close();
});
In fact, whenever i searched to fix the problem typing Mongo atlas in the search bar, the results are like How to delete cluster in mongo atlas even though i'm typing delete database in mongo atlas. So i don't know if a database can be deleted in mongo atlas.
Thank you in advance.

Looks like you are confusing "Atlas Project" security with "Database Access".
If you are looking for removing a database from an Atlas Cluster, the "Database User" you are using to login in your Mongo Client needs to have "dbAdmin" role in the related database. You can then perform related operations using your database user via your Mongo client programmatically.
You can refer to https://docs.atlas.mongodb.com/security-add-mongodb-users/ for managing database users and security roles.

You can log into Atlas, click the cluster name, click the "collections" tab, then when you hover over the database name on the left, there will appear a garbage can icon, which will delete the DB (assuming your user has proper permissions)
If you want to delete the db in code, there's no way to do it directly from mongoose, but you can if you access the underlying mongodb driver:
mongoose.connection.db.dropDatabase(cb)

Related

How to access one single collection in a database in MongoDB

When connecting to MongoDB with a Node.JS application using express, how do you connect to just one collection if the database has multiple collections?
I have the following MONGODB_URI:
MONGODB_URI=mongodb+srv://username:******#cluster0.dayw5.mongodb.net/phonebook?retryWrites=true&w=majority
The database "phonebook" has three collections, "numbers", "users" and "people". How do you change the MONGODB_URI to just connect to "numbers" ?
At the moment, the connection is successful, but nothing is being fetched.
You don't; the connection URI is granular to the database only, in your case phonebook. From the resources returned, you must specify a collection to access e.g. coll = db['users'] and then perform operations against that collection object e.g.
c = coll.find({name:"foo"});
c.forEach(function(doc) {
printjson(doc);
});
Both answers given above are basically correct.
I tried to connect to an existing collection but was unable to do so. Instead, MongoDB automatically creates a new collection in the database and gives it a new, custom name: "people" in my case which I did not specify anywhere.

Updating pre-existing things already in a database mongodb

I'm currently using mongodb in a express application via mongoose and a random thought came upon me. What would happen if say you had a site with users and later on you made a update and needed to add a new field to all the user models. how would you go about updating all pre-existing users with the new field.
You would use updateMany in your mongo shell (or using driver - the same):
db.user.updateMany({}, { $set: { newField: value } });

MongoDB custom user roles - "user is not allowed(...)"

I created a free tier cluster on MongoDB Atlas (it has 3 shards) and I want my Node.js app to connect with a database I created there, using a specific user, that will be restricted from using any other database than the one inteded for this app.
So step by step.
I create a database called, let's say, test.
I create a role here - I go to Security -> MongoDB Roles -> Add New Custom Role and I give it all Collection actions and all Database actions and roles to test
Time for a user, so again Security -> MongoDB Users -> Add New User and I assign a previously created role to it so it has access only to test database. So now I have 2 users - atlasAdmin and my created user.
That's where the problem occurs, when I use admin user in my app to connect, .find() or .create() it works fine all the time. With a user with custom role, it works for like 10mins/1 connection (until I shut down the local server I have my node app on) and the next time I get an error that "user is not allowed to perform action (...)".
I tried everything, tinkering with a string I use to connect, updating mongoose (I use it in my app), creating user and custom role using mongodb shell but nothing seems to work.
HOWEVER:
if I have this custom user, my app connects with it to the database and it works, then on the next connection it stops working AND I go here and just click UPDATE USER without changing anything there (I just click edit next to the user and then update) then wait for the cluster to make changes, it will work again for like +/- one connection.
everything works just fine if my app uses admin account
Anyone had similar problem? Screenshot of the error I was also thinking that it might be because of how many times I try to connect with mongo from the app (I use nodemon so everytime I save a file with changes, server restarts, thus connecting to database again) but I think that's not the case - if it was, why would I be able to make it work with admin user?
The string I use to connect with mongo:
// DATABASE SETUP
var dbURL = 'mongodb://[cluster0:port],[cluster1:port],[cluster2:port]/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true';
var options = {
useNewUrlParser: true,
dbName: "test"
user: [login],
pass: [pass]
};
mongoose.connect(dbURL, options);
I have also encountered this problem on Atlas Free tier, not just on NodeJS but Java as well
For now, you can try mitigating this problem by using a default role instead of having a custom one
On the MongoDB Users tab, click "Edit" on your user => Add Default Privileges
Picture 1
Then select "readWrite" and type your database name on the first field, then save the user
Picture 2
Or, if you want database administration, add another field with "dbAdmin" role
Picture 3
At least that's how I solved it. I hope this helps.
Side note: You can also use the shorter connection string (MongoDB+SRV) and it would still work.

Authentication error when connecting to specific mongodb database

I am currently using nodejs with mongodb native driver. So my mongodb has been set with admin auth with root role, so I can log in using robomongo or command line just fine. So back to my project, I m able to connect to mongodb just fine if i set my connection string:
mongodb://admin:password#localhost:27017/
However, if I use this connection string:
mongodb://admin:password#localhost:27017/specificdb
It return as:
MongoError: Authentication failed
I am able to access the db using command and robomongo, is there anything I can do? I have added the admin user under the db, but still got the same problem.
The database you specify is the one you authenticate on. If the user is not known/has no roles for that database it cannot authenticate to it.
https://docs.mongodb.com/manual/reference/connection-string/
What you can do is either create the (or a new) user for that database or use an authentication database parameter.
this worked for me :
first solution on connection :
mongoose.connect('mongodb://....', {
// add this line
authSource:"admin",
....
})
or second solution add to the uri "?authSource=admin" :
mongodb://user:password#host/yourDB?authSource=admin
** to note that I am using mongoose and this is the documentation specefic statement and the url :
authSource - The database to use when authenticating with user and pass. In MongoDB, users are scoped to a database. If you are getting an unexpected login failure, you may need to set this option.
https://mongoosejs.com/docs/connections.html#options

User specific database in MongoDB

I am currently working on an inventory management software in Node js and MongoDB. I am pretty new to MongoDB, having worked in Oracle and MySQL for most of my projects.
Is it possible to create a separate database schema for every client who uses my software, with each client having access only to his copy of the database schema and collections?
The equivalent of selecting data in Oracle database would be
Select * from User1.table,
Select * from User2.table etc
Also, if it were possible, how would it be implemented using a node js mongo db client like mongoose?
I looked at MongoDB documentation, but it talks mainly about adding users to a database for authorization.
I apologize if it seems like a silly question, but id appreciate it if someone could point me in the right direction for this.
Before starting to invest a lot of time in the development of your project, check out other possible approaches to the scenario that you are trying to build.
I did a quick search on SO and found some additional threads with similar scenarios:
MongoDB Database vs. Collection
MongoDB Web App - Database per User
Additional info about mongoose database creation
Whenever you call the connect method on the mongoose object, you are either connecting to an existing database or you are creating it in case it doesn't already exist.
You could have a function that allows you to pass in a name argument with the name and create databases programmatically:
function createDatabase(name) {
var conn_string = 'mongodb://localhost/';
if (typeof name == 'string') {
conn_string += name;
}else{
return false;
}
mongoose.connect(conn_string);
}
Also, be aware that a database will be created when you first insert a record in a collection of that particular database.
It is not sufficient to only connect to the database, you also have to insert a record.
As per my previous example, you could also pass a schema parameter to the function, tailored to each user's profile and fire an insert statement after you connect to that database.

Resources