0

Basically, I have a database in Mongodb and I want to be able to search for specific things in it. I want to have a javaScript file called search.js which takes in these parameters on the command line/terminal

node search.js --output=file.txt --maxItems=2 

This should run this search in the database:

db.DatabaseName.find().limit(2)

and print the results of that to the specified file beside the output parameter. I should note that if --output isn't specified it should just default to the terminal or --maxItems isn't specified then it should print all items in the result.

I can get most of the functionality working individually but I'm having trouble putting it into a JavaScript file and taking arguments from the command line. Can anyone lead me in the right direction?

Community
  • 1
  • 1
iamtesla
  • 423
  • 2
  • 5
  • 18
  • See [How to pass command line arguments to Nodejs](http://stackoverflow.com/questions/4351521/how-to-pass-command-line-arguments-to-node-js) and [Writing files in Nodejs](http://stackoverflow.com/questions/2496710/writing-files-in-node-js) – Carpetfizz Mar 02 '15 at 03:25
  • @Carpetfizz I can write to a file but I'm not sure how I'd pass those arguments to Mongo, and how to run the queries. – iamtesla Mar 02 '15 at 03:33

1 Answers1

3

I somehow get the feeling here that what you are actually asking is indeed a lot more broad than what you are letting on in the question. And it really is since you seem to be asking for a "nodejs" version of "mongoexport". That really is way to broad an ask, but we can at least cover the basics.

In addition to the sort of "options" you want specified, you also want a good sensible number of defaults in addition to "required" input, which should primarily be the collection name as there would be no point to hard-coding a default for that value.

That options processing really should be something beyond just the rudimentary argument passing. node-getopt is an example that implements things in a reasonable industry standard way.

So this listing covers the basics of how to handle things. Adding other functionality is up to you:

var fs = require('fs'),
    MongoClient = require('mongodb').MongoClient,
    Getopt = require('node-getopt');

var getopt = new Getopt([
  [ 'o',  'output-file=ARG',    'Output file or STDOUT' ],
  [ 'm',  'maxItems=ARG',       'Maximum output items' ],
  [ '',   'host=ARG',           'optional host' ],
  [ '',   'port=ARG',           'optional port' ],
  [ 'd',  'database=ARG',       'optional database' ],
  [ 'h',  'help',               'display this help' ],
  [ 'v',  'version',            'show version' ]
]).bindHelp();

var opt = getopt.parse(process.argv.slice(2));

if ( opt.argv[0] == undefined ) {
  console.log("collection name must be included");
  process.exit(-1);
}

var options = {
  "host": opt.options.host || 'localhost',
  "port": opt.options.port || 27017,
  "database": opt.options.database || 'test',
  "maxItems": 0,
};

try {
  options.maxItems = parseInt(opt.options.maxItems || options.maxItems);
  if ( isNaN(options.maxItems) )
    throw new Error("maxItems needs to be numeric");
} catch(e) {
  console.log(e);
  process.exit();
}

console.log( options );

MongoClient.connect(
  'mongodb://' +   options.host + ':' + options.port
  + '/' + options.database,
  function(err,db) {
    if (err) throw err;

    db.collection(opt.argv[0],function(err,collection) {
      if (err) throw err;

      var stream = collection.find().limit(options.maxItems).stream();

      stream.on('data',function(data) {
        stream.pause();
        if ( !options.hasOwnProperty('writer') ) {
          try {
            options.writer = opt.options.hasOwnProperty("output-file") ?
              fs.openSync( opt.options["output-file"], 'w' )
              : process.stdout.fd;
          } catch(e) {
            throw e;
         }
        }

        var block = JSON.stringify(data) + "\n";
        fs.writeSync( options.writer, block );
        stream.resume();
      });

      stream.on('end',function() {
        db.close();
      });

      stream.on('error',function(err) {
        throw err;
      });

    });
  }
);

So if I just called that sample.js then I could run for example like:

node sample.js messages --maxItems 10 --output-file output.json
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317