76

I've been using mongo and script files like this:

$ mongo getSimilar.js

I would like to pass an argument to the file:

$ mongo getSimilar.js apples

And then in the script file pick up the argument passed in.

var arg  = $1;
print(arg);
Brig
  • 10,211
  • 12
  • 47
  • 71

7 Answers7

123

Use --eval and use shell scripting to modify the command passed in.

mongo --eval "print('apples');"

Or make global variables (credit to Tad Marshall):

$ cat addthem.js
printjson( param1 + param2 );
$ ./mongo --nodb --quiet --eval "var param1=7, param2=8" addthem.js
15
jcollum
  • 43,623
  • 55
  • 191
  • 321
  • 1
    This doesn't work with mapreduce, the reduce() function doesn't have access to the params (ReferenceError: ... is not defined near ...) – Thomas Sep 06 '13 at 12:35
  • 4
    --eval is very useful. say we want to quickly change secondary to become primary in a replication set. Use a script `conf = rs.conf() conf.members.forEach( function (member) { member.priority = 0.5 } ) conf.members[memberId].priority = 1 // rs.reconfig(conf)` save this script in chooseprimary.js and run with `mongo --eval "var memberId=3" chooseprimary.js` . memberId should be the id of the secondary you wish to become primary. Just make sure to execute mongo --eval on the Primary server. :) – Developer Marius Žilėnas Feb 01 '16 at 12:26
29

You can't do that, but you could put them in another script and load that first:

// vars.js
msg = "apples";

and getSimilar.js was:

print(msg);

Then:

$ mongo vars.js getSimilar.js
MongoDB shell version: blah
connecting to: test
loading file: vars.js
loading file: getSimilar.js
apples

Not quite as convenient, though.

kris
  • 23,024
  • 10
  • 70
  • 79
3

Set a shell var:

password='bladiebla'

Create js script:

cat <<EOT > mongo-create-user.js
print('drop user admin');
db.dropUser('admin');
db.createUser({
user: 'admin',
pwd: '${password}',
roles: [ 'readWrite']
});
EOT

Pass script to mongo:

mongo mongo-create-user.js
robodo
  • 430
  • 3
  • 8
2

2022 update:

when using mongosh you can read the execution arguments from process.argv

mongosh script.js param1 param2 
// process.argv will be [.... , 'param1', param2']

the tricky bit is that mongosh will try to execute the parameters (e.g. param1 and param2) as additional scripts, but this can be prevented by ending the script using quit(). (TBH, I'm not sure it's by design / intended / documented)

Nir
  • 1,225
  • 12
  • 8
1

I used a shell script to pipe a mongo command to mongo. In the mongo command I used an arg I passed to the shell script (i.e. i used $1):

#!/bin/sh

objId=$1
EVAL="db.account.find({\"_id\" : \"$objId\"})"
echo $EVAL | mongo localhost:27718/balance_mgmt --quiet
skypjack
  • 49,335
  • 19
  • 95
  • 187
Tony
  • 19
  • 1
  • Shouldn't that be `find({\"_id\" : ObjectId(\"$objId\")})`? Or is there a way to set mongo so that you don't have to use the `ObjectId()` guy? –  Dec 12 '17 at 16:44
0

I wrote a small utility to solve the problem for myself. With the mongoexec utility, you would be able to run the command ./getSimilar.js apples by adding the following to the beginning of your script:

#!/usr/bin/mongoexec --quiet

Within the script, you can then access the arguments as args[0].

https://github.com/pveierland/mongoexec

user764486
  • 160
  • 5
  • Doesn't work; I'm getting access denied. `sudo` doesn't do the trick. Changing the shebang to point to the executable located in user directory (rather than /usr/bin) doesn't work. Was all excited to use it. Wish I could get it to work. –  Dec 12 '17 at 16:30
  • 1
    @Bear The instructions fail to mention that the script must be executable. If you run "sudo chmod +rx /usr/bin/mongoexec" it should work. – user764486 Dec 13 '17 at 13:24
0

I solved this problem, by using the javascript bundler parcel: https://parceljs.org/

With this, one can use node environment variables in a script like:

var collection = process.env.COLLECTION;

when building with parcel, the env var gets inlined:

parcel build ./src/index.js --no-source-maps

The only downside is, that you have to rebuild the script every time you want to change the env vars. But since parcel is really fast, this is not really a problem imho.

beac0n
  • 50
  • 1
  • 6