Use [DB] for Mongodb with shell - mongodb

I am researching now the simple "use" command for the mongo command. Please help me.
I just want save the my query in a file, but before that i need to connect to a certain database. For that i tried to find a "use" command like in sql, but could not find anything.
I just want to execute something like
mongo ....--use [db] --eval 'db.find' > save.query

In your question, you didn't specify what platform you're using, are you using Linux? Windows? Anyway, if you want to use the command line for mongo db then I would recommend to use the mongodb shell. Download the mongodb shell https://www.mongodb.com/try/download/shell and select what platform you're using.

https://www.mongodb.com/docs/mongodb-shell/run-commands/#mongosh-usage
That sais you have use <database> command

I just got it. You can just add the database name:
mongo [dbname] --host etc.
and it worked.

This is the easiest way in linux:
Option 1 ( command line params )
echo "db.exampleollection.find({}).forEach(function(d){printjson(d)})" | mongo --quiet exampledatabase --host "examplehost" --port "examplePort" --authenticationDatabase=admin -u "exampleuser" -p "examplepassword" > output.json
Explained:
Send the command you need to execute via echo to the mongo shell and redirect the output to the result file.
Add the option --quiet to suppress the shell printed info
You can provide the database directly in as comman line argument.
Option 2 : same way but URI format:
echo "show collections" | mongo "mongodb://user:pass#host:port/database?authSource=admin" --quiet

Related

Cannot mongodump to a single archive

I'm trying to dump a MongoDB database to an archive. Using the following command as given in documentation.
sudo mongodump --uri=mongodb://username:password#host:27017/dbname?authMechanism=SCRAM-SHA-1&authSource=authdb --archive=file.archive
But it doesn't dump as expected rather it creates a dump folder with .json file for each collection, which should be a single archive file as given.
It also shows the following error -
--archive=file.archive: command not found
Mongo version -
MongoDB shell version v3.6.3
I had this problem & I figured out the reason it was happening.
The command I was running was
sudo /usr/bin/mongodump --uri=mongodb+srv://{username}:{password}#{atlasendpoint}.mongodb.net/?retryWrites=true&w=majority --archive={filename}.archive --gzip 2>&1
I was getting the same error as you. I change the shell command by wrapping quotation marks around the URL; this fixed it for me.
sudo /usr/bin/mongodump --uri="mongodb+srv://{username}:{password}#{atlasendpoint}.mongodb.net/?retryWrites=true&w=majority" --archive={filename}.archive --gzip 2>&1

How can I disable connection messages in mongo shell [duplicate]

I want to execute mongo commands in shell script, e.g. in a script test.sh:
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
When I execute this script via ./test.sh, then the connection to MongoDB is established, but the following commands are not executed.
How to execute other commands through shell script test.sh?
You can also evaluate a command using the --eval flag, if it is just a single command.
mongo --eval "printjson(db.serverStatus())"
Please note: if you are using Mongo operators, starting with a $ sign, you'll want to surround the eval argument in single quotes to keep the shell from evaluating the operator as an environment variable:
mongo --eval 'db.mycollection.update({"name":"foo"},{$set:{"this":"that"}});' myDbName
Otherwise you may see something like this:
mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY SyntaxError: Unexpected token :
Put your mongo script into a .js file.
Then execute mongo < yourFile.js
Ex:
demo.js //file has your script
use sample //db name
show collections
keep this file in "c:\db-scripts"
Then in cmd prompt go to "c:\db-scripts"
C:\db-scripts>mongo < demo.js
This will execute the code in mongo and shows the output
C:\db-scripts>mongo < demo.js
Mongo shell version: 3.0.4
Connecting to: test
switched to db sample
users //collection name
tasks //collection name
bye
C:\db-scripts>
This works for me under Linux:
mongo < script.js
For newer version of mongodb
mongosh < script.js
Put this in a file called test.js:
db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
print(collection);
});
then run it with mongo myDbName test.js.
There is an official documentation page about this as well.
Examples from that page include:
mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
The shell script below also worked nicely for me... definite had to use the redirect that Antonin mentioned at first... that gave me the idea to test the here document.
function testMongoScript {
mongo <<EOF
use mydb
db.leads.findOne()
db.leads.find().count()
EOF
}
In case you have authentication enabled:
mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
For newer version
mongosh -u username -p password --authenticationDatabase auth_db_name < your_script.js
I use the "heredoc" syntax, which David Young mentions. But there is a catch:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
The above will NOT work, because the phrase "$exists" will be seen by the shell and substituted with the value of the environment variable named "exists." Which, likely, doesn't exist, so after shell expansion, it becomes:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
In order to have it pass through you have two options. One is ugly, one is quite nice. First, the ugly one: escape the $ signs:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
I do NOT recommend this, because it is easy to forget to escape.
The other option is to escape the EOF, like this:
#!/usr/bin/sh
mongo <db> <<\EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Now, you can put all the dollar signs you want in your heredoc, and the dollar signs are ignored. The down side: That doesn't work if you need to put shell parameters/variables in your mongo script.
Another option you can play with is to mess with your shebang. For example,
#!/bin/env mongo
<some mongo stuff>
There are several problems with this solution:
It only works if you are trying to make a mongo shell script executable from the command line. You can't mix regular shell commands with mongo shell commands. And all you save by doing so is not having to type "mongo" on the command line... (reason enough, of course)
It functions exactly like "mongo <some-js-file>" which means it does not let you use the "use <db>" command.
I have tried adding the database name to the shebang, which you would think would work. Unfortunately, the way the system processes the shebang line, everything after the first space is passed as a single parameter (as if quoted) to the env command, and env fails to find and run it.
Instead, you have to embed the database change within the script itself, like so:
#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
As with anything in life, "there is more than one way to do it!"
In my setup I have to use:
mongo --host="the.server.ip:port" databaseName theScript.js
For newer version of mongodb
mongosh --host="the.server.ip:port" databaseName theScript.js
How about this:
echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
Create a script file; write commands:
#!/bin/sh
mongo < file.js
For newer versions
mongosh < file.js
In file.js write your mongo query:
db.collection.find({"myValue":null}).count();
As suggested by theTuxRacer, you can use the eval command, for those who are missing it like I was, you can also add in your db name if you are not trying to preform operation on the default db.
mongo <dbname> --eval "printjson(db.something.find())"
Newer version of mongodb
mongosh <dbname> --eval "printjson(db.something.find())"
In my case, I can conveniently use \n as separator for the next mongo command I want to execute then pipe them to mongo
echo $'use your_db\ndb.yourCollection.find()' | mongo
Newer version of mongodb
echo $'use your_db\ndb.yourCollection.find()' | mongosh
Thank you printf! In a Linux environment, here's a better way to have only one file run the show. Say you have two files, mongoCmds.js with multiple commands:
use someDb
db.someColl.find()
and then the driver shell file, runMongoCmds.sh
mongo < mongoCmds.js
Newer version of mongodb
mongosh < mongoCmds.js
Instead, have just one file, runMongoCmds.sh containing
printf "use someDb\ndb.someColl.find()" | mongo
Bash's printf is much more robust than echo and allows for the \n between commands to force them on multiple lines.
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
--shell flag can also be used for javascript files
mongo --shell /path/to/jsfile/test.js
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
Recently migrated from mongodb to Postgres. This is how I used the scripts.
mongo < scripts.js > inserts.sql
Read the scripts.js and output redirect to inserts.sql.
scripts.js looks like this
use myDb;
var string = "INSERT INTO table(a, b) VALUES";
db.getCollection('collectionName').find({}).forEach(function (object) {
string += "('" + String(object.description) + "','" + object.name + "'),";
});
print(string.substring(0, string.length - 1), ";");
inserts.sql looks like this
INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
If you want to handle it with one line it's an easy way.
file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234)
cat file.sh | mongo <EXPECTED_COLLECTION>
Single shell script solution with ability to pass mongo arguments (--quiet, dbname, etc):
#!/usr/bin/env -S mongo --quiet localhost:27017/test
cur = db.myCollection.find({});
while(cur.hasNext()) {
printjson(cur.next());
}
The -S flag might not work on all platforms.
When using a replicaset, writes must be done on the PRIMARY, so I usually use syntax like this which avoids having to figure out which host is the master:
mongo -host myReplicaset/anyKnownReplica
The legacy mongo shell has been removed from MongoDB with the version 6 release in 2022
There is a new way to execute shell scripts using the new shell, mongosh
From the shell documentation on writing scripts:
You can use mongosh to execute a script from the command line without entering the mongosh console
To specify the filename, use the --file or -f parameter to specify the filename
You may also need to specify connection information

mongo command line vs shell: different results

I'm puzzled by a problem I'm having with the Mongo Shell producing different variations on the output.
When I log into the mongo shell and run the simplest of queries, such as:
db.database.findOne();
I get a document returned.
When I invoke the same command through the --eval option on the command line, I get a different result: (xx's redact sensitive info)
mongo -u xxx -p xxx xxxx --eval 'db.database.findOne();'
MongoDB shell version: 3.0.6
connecting to: xxxx
[object Object]
And when I put this command in a file and try it, I get no output at all.
mongo -u xxx-p xxx xxxx example.js
MongoDB shell version: 3.0.6
connecting to: xxxx
(I just get returned to a command line here)
Example.js contains:
db.database.findOne();
What part of the Mongo shell manual did I miss that explains this behavior?
My goal is to be able to feed the output of my mongo query into a shell script.
When a findOne() is run within the shell it will print the result in JSON as a convenience. To print the same via shell script or eval you need to print the return value via a printjson() call:
mongo -u xxx -p xxx xxxx --eval 'printjson(db.database.findOne());'
For more on scripting with the mongo shell see the official MongoDB Shell docs.

How do I drop a MongoDB database from the command line?

What's the easiest way to do this from my bash prompt?
Like this:
mongo <dbname> --eval "db.dropDatabase()"
More info on scripting the shell from the command line here: https://docs.mongodb.com/manual/tutorial/write-scripts-for-the-mongo-shell/#scripting
Edit:
In Mongo 6.0 mongo was removed and replaced with mongosh which has to be installed separately. More info here: https://www.mongodb.com/docs/mongodb-shell/#mongodb-binary-bin.mongosh
The best way to do it is from the mongodb console:
> use mydb;
> db.dropDatabase();
Alternatively, you can stop mongod and delete the data files from your data directory, then restart.
Hint: you can also move the data files to a subfolder, and delete them if you're sure you no longer need them.
I found this easy to remember:
mongo //to start the mongodb shell
show dbs //to list existing databases
use <dbname> //the <dbname> is the database you'd like to drop
db //should show <dbname> just to be sure I'm working with the right database
db.dropDatabase() //will delete the database & return { "dropped" : "<dbname>", "ok" : 1 }
You don't need heredocs or eval, mongo itself can act as an interpreter.
#!/usr/bin/env mongo
var db = new Mongo().getDB("someDatabase");
db.dropDatabase();
Make the file executable and run it.
Start MongoDB
Command for Database drop is :
1. first select the database which you want to delete
use < database name >
2. Then use this..
db.dropDatabase()
You could also use a "heredoc":
mongo localhost/db <<EOF
db.dropDatabase()
EOF
Results in output like:
mongo localhost/db <<EOF
db.dropDatabase()
EOF
MongoDB shell version: 2.2.2
connecting to: localhost/db
{ "dropped" : "db", "ok" : 1 }
bye
I like to use heredocs for things like this, in case you want more complex sequence of commands.
Here are some use full delete operations for mongodb using mongo shell
To delete particular document in collections: db.mycollection.remove( {name:"stack"} )
To delete all documents in collections: db.mycollection.remove()
To delete collection : db.mycollection.drop()
to delete database :
first go to that database by use mydb command and then
db.dropDatabase()
directly from command prompt or blash : mongo mydb --eval "db.dropDatabase()
Other way:
echo "db.dropDatabase()" | mongo <database name>
Execute in a terminal:
mongo // To go to shell
show databases // To show all existing databases.
use <DATA_BASE> // To switch to the wanted database.
db.dropDatabase() // To remove the current database.
Open another terminal window and execute the following commands,
mongodb
use mydb
db.dropDatabase()
Output of that operation shall look like the following
MAC:FOLDER USER$ mongodb
> show databases
local 0.78125GB
mydb 0.23012GB
test 0.23012GB
> use mydb
switched to db mydb
>db.dropDatabase()
{ "dropped" : "mydb", "ok" : 1 }
>
Please note that mydb is still in use, hence inserting any input at that time will initialize the database again.
Open a terminal and type:
mongo
The below command should show the listed databases:
show dbs
/* the <dbname> is the database you'd like to drop */
use <dbname>
/* the below command will delete the database */
db.dropDatabase()
The below should be the output in the terminal:
{
"dropped": "<dbname>",
"ok": 1
}
Using Javascript, you can easily create a drop_bad.js script to drop your database:
create drop_bad.js:
use bad;
db.dropDatabase();
Than run 1 command in terminal to exectue the script using mongo shell:
mongo < drop_bad.js
Eventhough there are several methods, The best way (most efficient and easiest) is using db.dropDatabase()
In you command prompt, First connect to mongodb using following command:
mongo -h [host-name]:[port:number] -d [dbname] -u [username] -p [password]
you will be accessing db with <dbname>.
Run the following command to drop the whole database:
db.dropDatabase()
one liner remote remove all collections from mongo database
note must use --host, (-h is help for mongo command), and -d is not an option, select the db and command after password.
mongo --host <mongo_host>:<mongo_port> -u <db_user> -p <db_pass> <your_db> --eval "db.dropDatabase()"
Surprised that we haven't seen this variation come up. This minimizes extra args on the command line and explicitly shows the DB being switched to FOO and then dropped:
$ mongo --host "mongodb://machine:port" --eval 'db.getSiblingDB("FOO").dropDatabase();'
LogIn into your mongoDB command line:
And type the below commands.
use "YOUR_DATABASE_NAME";
db.dropDatabase();
Drop a MongoDB database using python:
import argparse
import pymongo
if __name__ == "__main__":
"""
Drop a Database.
"""
parser = argparse.ArgumentParser()
parser.add_argument("--host", default='mongodb://localhost:27017',
help="mongodb URI [default: %(default)s]")
parser.add_argument("--database", default=None,
help="database name: %(default)s]")
args = parser.parse_args()
client = pymongo.MongoClient(host=args.host)
if args.database in client.list_database_names():
client.drop_database(args.database)
print(f"Dropped: '{args.database}'")
else:
print(f"Database '{args.database}' does not exist")
In order to be really sure that you drop the correct database use
mongo <connection properties> --eval "db.getSiblingDB('dbname').dropDatabase()"
See Authentication failure while trying to save to mongodb to understand the concerns.
You can first switch to your database which you want to delete. Then you can delete the same by using the command dropDatabase().
Code :
>use dbName
>db.dropdataBase()
The result will be :
{ "dropped" : "dbName", "ok" : 1 }
If you want to delete a specific collection in a database, then switch to the database and enter the following command.
Code:
>use dbName
db.collection.drop()
The result will be :
true
If you want a better understanding of MongoDB shell commands it's
better to follow the documentation always.
Link to the documentation :
https://www.mongodb.com/docs/manual/reference/method/#std-label-js-administrative-methods
db will show the current Database name
type: db.dropDatabase();
1- select the database to drop by using 'use' keyword.
2- then type db.dropDatabase();
use following command from mongo shell to drop db
use <database name>;
db.dropDatabase();

How to execute mongo commands through shell scripts?

I want to execute mongo commands in shell script, e.g. in a script test.sh:
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
When I execute this script via ./test.sh, then the connection to MongoDB is established, but the following commands are not executed.
How to execute other commands through shell script test.sh?
You can also evaluate a command using the --eval flag, if it is just a single command.
mongo --eval "printjson(db.serverStatus())"
Please note: if you are using Mongo operators, starting with a $ sign, you'll want to surround the eval argument in single quotes to keep the shell from evaluating the operator as an environment variable:
mongo --eval 'db.mycollection.update({"name":"foo"},{$set:{"this":"that"}});' myDbName
Otherwise you may see something like this:
mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY SyntaxError: Unexpected token :
Put your mongo script into a .js file.
Then execute mongo < yourFile.js
Ex:
demo.js //file has your script
use sample //db name
show collections
keep this file in "c:\db-scripts"
Then in cmd prompt go to "c:\db-scripts"
C:\db-scripts>mongo < demo.js
This will execute the code in mongo and shows the output
C:\db-scripts>mongo < demo.js
Mongo shell version: 3.0.4
Connecting to: test
switched to db sample
users //collection name
tasks //collection name
bye
C:\db-scripts>
This works for me under Linux:
mongo < script.js
For newer version of mongodb
mongosh < script.js
Put this in a file called test.js:
db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
print(collection);
});
then run it with mongo myDbName test.js.
There is an official documentation page about this as well.
Examples from that page include:
mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
The shell script below also worked nicely for me... definite had to use the redirect that Antonin mentioned at first... that gave me the idea to test the here document.
function testMongoScript {
mongo <<EOF
use mydb
db.leads.findOne()
db.leads.find().count()
EOF
}
In case you have authentication enabled:
mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
For newer version
mongosh -u username -p password --authenticationDatabase auth_db_name < your_script.js
I use the "heredoc" syntax, which David Young mentions. But there is a catch:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
The above will NOT work, because the phrase "$exists" will be seen by the shell and substituted with the value of the environment variable named "exists." Which, likely, doesn't exist, so after shell expansion, it becomes:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
In order to have it pass through you have two options. One is ugly, one is quite nice. First, the ugly one: escape the $ signs:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
I do NOT recommend this, because it is easy to forget to escape.
The other option is to escape the EOF, like this:
#!/usr/bin/sh
mongo <db> <<\EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Now, you can put all the dollar signs you want in your heredoc, and the dollar signs are ignored. The down side: That doesn't work if you need to put shell parameters/variables in your mongo script.
Another option you can play with is to mess with your shebang. For example,
#!/bin/env mongo
<some mongo stuff>
There are several problems with this solution:
It only works if you are trying to make a mongo shell script executable from the command line. You can't mix regular shell commands with mongo shell commands. And all you save by doing so is not having to type "mongo" on the command line... (reason enough, of course)
It functions exactly like "mongo <some-js-file>" which means it does not let you use the "use <db>" command.
I have tried adding the database name to the shebang, which you would think would work. Unfortunately, the way the system processes the shebang line, everything after the first space is passed as a single parameter (as if quoted) to the env command, and env fails to find and run it.
Instead, you have to embed the database change within the script itself, like so:
#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
As with anything in life, "there is more than one way to do it!"
In my setup I have to use:
mongo --host="the.server.ip:port" databaseName theScript.js
For newer version of mongodb
mongosh --host="the.server.ip:port" databaseName theScript.js
How about this:
echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
Create a script file; write commands:
#!/bin/sh
mongo < file.js
For newer versions
mongosh < file.js
In file.js write your mongo query:
db.collection.find({"myValue":null}).count();
As suggested by theTuxRacer, you can use the eval command, for those who are missing it like I was, you can also add in your db name if you are not trying to preform operation on the default db.
mongo <dbname> --eval "printjson(db.something.find())"
Newer version of mongodb
mongosh <dbname> --eval "printjson(db.something.find())"
In my case, I can conveniently use \n as separator for the next mongo command I want to execute then pipe them to mongo
echo $'use your_db\ndb.yourCollection.find()' | mongo
Newer version of mongodb
echo $'use your_db\ndb.yourCollection.find()' | mongosh
Thank you printf! In a Linux environment, here's a better way to have only one file run the show. Say you have two files, mongoCmds.js with multiple commands:
use someDb
db.someColl.find()
and then the driver shell file, runMongoCmds.sh
mongo < mongoCmds.js
Newer version of mongodb
mongosh < mongoCmds.js
Instead, have just one file, runMongoCmds.sh containing
printf "use someDb\ndb.someColl.find()" | mongo
Bash's printf is much more robust than echo and allows for the \n between commands to force them on multiple lines.
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
--shell flag can also be used for javascript files
mongo --shell /path/to/jsfile/test.js
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
Recently migrated from mongodb to Postgres. This is how I used the scripts.
mongo < scripts.js > inserts.sql
Read the scripts.js and output redirect to inserts.sql.
scripts.js looks like this
use myDb;
var string = "INSERT INTO table(a, b) VALUES";
db.getCollection('collectionName').find({}).forEach(function (object) {
string += "('" + String(object.description) + "','" + object.name + "'),";
});
print(string.substring(0, string.length - 1), ";");
inserts.sql looks like this
INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
If you want to handle it with one line it's an easy way.
file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234)
cat file.sh | mongo <EXPECTED_COLLECTION>
Single shell script solution with ability to pass mongo arguments (--quiet, dbname, etc):
#!/usr/bin/env -S mongo --quiet localhost:27017/test
cur = db.myCollection.find({});
while(cur.hasNext()) {
printjson(cur.next());
}
The -S flag might not work on all platforms.
When using a replicaset, writes must be done on the PRIMARY, so I usually use syntax like this which avoids having to figure out which host is the master:
mongo -host myReplicaset/anyKnownReplica
The legacy mongo shell has been removed from MongoDB with the version 6 release in 2022
There is a new way to execute shell scripts using the new shell, mongosh
From the shell documentation on writing scripts:
You can use mongosh to execute a script from the command line without entering the mongosh console
To specify the filename, use the --file or -f parameter to specify the filename
You may also need to specify connection information