Skip to content
Studio 3T - The professional GUI, IDE and client for MongoDB
  • Tools
    • Aggregation Editor
    • IntelliShell
    • Visual Query Builder
    • Export Wizard
    • Import Wizard
    • Query Code
    • SQL Query
    • Connect
    • Schema Explorer
    • Compare
    • SQL ⇔ MongoDB Migration
    • Data Masking
    • Task Scheduler
    • Reschema
    • More Tools and Features
  • Solutions
  • Resources
    • Knowledge Base
    • MongoDB Tutorials & Courses
    • Tool/Feature Documentation
    • Blog
    • Community
    • Testimonials
    • Whitepapers
    • Reports
  • Contact us
    • Contact
    • Sales Support
    • Feedback and Support
    • Careers
    • About Us
  • Store
    • Buy Now
    • Preferred Resellers
    • Team Pricing
  • Download
  • My 3T
search

Mongosh: How to Run More Processes

Posted on: 02/03/2023 by Dj Walker-Morgan

In the previous two parts of this series, we’ve looked at how to read and write files. But what’s the point of writing files if you can’t do anything with them after you’ve finished writing them? Well, you could always run another process to consume your file and do something with it. Until the arrival of Mongosh however, you would have had to do this manually. Now with Mongosh, we can leverage its access to the rich Node.js library to run a process.

The key to running processes is the child_process module of Node, specifically the execSync command.

child_process.execSync(command[, options])

If you look at the manual page, you’ll see there are many options for this command but that’s the nature of running processes; there are a lot of moving parts.

Getting practical with the mongo shell

Let’s look at a practical example, using what we created in the previous article, when we turned a MongoDB collection into a HTML page. In that case we wrote a HTML table of all the matching records to a file and did nothing to publish it to the world. Let’s fix that now.

Our “Publish” command

We don’t want to get into the weeds over what or how we are publishing to the web. For this example, publishing will consist of calling a shell script called publish.sh with a file name. And all that script will do is copy the file.

cp $1 /tmp/$1

That’s it: it’s enough to show the principles at work. All this does is copy the named file (from the first argument – $1) over to /tmp/ with the same name. Let’s save that as publish.sh in our home directory, where we write our page.html file.

Calling the Publish command

At the end of our script, we can now add this:

var a = child_process.execSync("sh publish.sh page.html", 
       { cwd:"/Users/dj" }, 
       (error, stdout, stderr) => {
           if (error) {
           print(`exec error: ${error}`);
           return; }
        }
);

The first parameter to our execSync call is the command:

sh publish.sh page.html

This calls the default shell (sh) and asks it to run publish.sh in the current directory. And we give that script the argument page.html. Nothing too out of the ordinary there. This is where you could drop in another executable or command to be run.

Where are we currently working?

The thing you should be asking is “How does the script know where all these HTML files are?” The answer is, it doesn’t. And that’s why we have one parameter being set in the options:

{ cwd:"/Users/dj" }, 

This sets the current working directory (cwd) to my home directory, where I previously wrote out the page.html file and where I wrote and saved the publish.sh script. With this set, when sh runs it will look in the current working directory for publish.sh (and find it) and when publish.sh runs it will look for page.html in the current working directory, and find it just as we wrote it.

The last part of the execSync parameters is a function which defines what happens when the command being run finishes running. This function is called after it exits.

(error, stdout, stderr) => {

It defines an anonymous function that will be handed the error (if any), the command’s standard output and the command’s standard error output. It’s up to the function what is done with these parameters.

     if (error) {
           print(`exec error: ${error}`);
           return; }
        });

And in this case, we only respond if an error has been reported, by printing out the error. In this case we don’t do anything else. And that’s the end of the call.

Running the script

When you are ready, click the Run button and the script will run, creating page.html in your home directory, then running a shell script to copy that file to /tmp. It’s as simple as that. This is, of course, just an example. What you do with this capability depends on your own workflows.

One important point, with Studio 3T, the ability to schedule scripts like these opens the way to even more powerful automation. For example, any project which needs to produce public reports, for compliance or transparency, would benefit from scheduling a fully automated web publication process to remove the possibility of the report not being produced. 

Here’s the whole example script in its entirety:

db = db.getSiblingDB("sample_training");
var cursor=db.getCollection("companies").find(
    {
        "$and" : [
            {
                "homepage_url" : {
                    "$exists" : true
                }
            },
            {
                "homepage_url" : {
                    "$ne" : null
                }
            },
            {
                "homepage_url" : {
                    "$ne" : ""
                }
            }
        ]
    },
    {
        "name" : 1.0,
        "homepage_url" : 1.0
    }
).sort(
    {
        "name" : 1.0
    }
);

process.chdir("/Users/dj/");
var out = fs.openSync('page.html', 'w')
fs.writeSync(out,"<html><body><table>\n")
while (cursor.hasNext()) {
    var r = cursor.next();
    fs.writeSync(out,`<tr><td><a href='${r.homepage_url}'>${r.name}</a></td></tr>\n`);
}
cursor.close();
fs.writeSync(out,"</table></body></html>\n")
fs.closeSync(out);

var a = child_process.execSync("sh publish.sh page.html",
      { cwd:"/Users/dj" },
      (error, stdout, stderr) => {
          if (error) {
          print(`exec error: ${error}`);
          return; }
        }
);

Final notes on our MongoDB shell example

First, we’ve only touched on what you can do with execSync. As I mentioned, there are many options available with it, beyond cwd, which let you configure the environment, path and behavior of the executable when run. 

Secondly, reading and writing files or running processes are just a few of the things that are possible to do using Mongosh, now that it has a full JavaScript/NodeJS engine underpinning it. For example, network connections to get data from APIs or to trigger web automation are possible, although admittedly currently a little fiddly in terms of the gymnastics needed to make those calls simply and reliably; short version, there’s no synchronous versions of the web/network calls. But, the state of the art in what underlies Mongosh has moved on, so look out in future for those improvements to appear in Mongosh too, making easy networking possible.

Finally, have fun with Mongosh, it’s the most powerful thing! In creating this series, our experiments have led to creating self publishing map websites which are automatically deployed to the web, complete with fresh data every day and emailed reports landing in inboxes with attached spreadsheets. What will you create? Let us know!


How helpful was this article?
This article was hideous
This article was bad
This article was ok
This article was good
This article was great
Thank you for your feedback!

About The Author

Dj Walker-Morgan

Dj has been around since Commodore had Pets and Apples grew everywhere. With a background in Unix and development, he's been around the technology business writing code or writing content ever since.

Related articles

  • Mongosh: How To Read More Files 
  • Mongosh: How To Write More Files
  • Why do I see an error when I re-run an IntelliShell script? #Studio3T_AMA
  • Lesson 2, Exercise 1: Using IntelliShell to build and run find statements
  • Lesson 2, Exercise 2: Using Visual Query Builder to build and run find statements

Tags

2022 academy aggregation AMA atlas Certification christmas community connections culture date tags events export features hackolade import intellishell In Use JSON knowledge base migration modelling mongodb mongoodb mongosh My 3T productivity query regex releases schema security SQL Studio 3T tasks time series tips updates webinar windows

Browse by MongoDB topic

  • Connecting to MongoDB
  • Database Administration & Security
  • Getting Started with MongoDB
  • Getting Started with Studio 3T
  • Import/Export
  • Job Automation & Scheduling
  • MongoDB Aggregation Framework
  • MongoDB/Studio 3T Workshops
  • Performance
  • Query & CRUD Operations
  • Reference
  • Schema
  • Studio 3T Licensing
  • Support and other resources
  • Working with MongoDB & SQL
  • Working with MongoDB Atlas

Studio 3T

MongoDB Enterprise Certified Technology PartnerSince 2014, 3T has been helping thousands of MongoDB developers and administrators with their everyday jobs by providing the finest MongoDB tools on the market. We guarantee the best compatibility with current and legacy releases of MongoDB, continue to deliver new features with every new software release, and provide high quality support.

Find us on FacebookFind us on TwitterFind us on YouTubeFind us on LinkedIn

Education

  • Free MongoDB Tutorials
  • Connect to MongoDB
  • Connect to MongoDB Atlas
  • Import Data to MongoDB
  • Export MongoDB Data
  • Build Aggregation Queries
  • Query MongoDB with SQL
  • Migrate from SQL to MongoDB

Resources

  • Feedback and Support
  • Sales Support
  • Knowledge Base
  • FAQ
  • Reports
  • White Papers
  • Testimonials
  • Discounts

Company

  • About Us
  • Blog
  • Careers
  • Legal
  • Press
  • Privacy Policy
  • EULA

© 2023 3T Software Labs Ltd. All rights reserved.

  • Privacy Policy
  • Cookie settings
  • Impressum

We value your privacy

With your consent, we and third-party providers use cookies and similar technologies on our website to analyse your use of our site for market research or advertising purposes ("analytics and marketing") and to provide you with additional functions (“functional”). This may result in the creation of pseudonymous usage profiles and the transfer of personal data to third countries, including the USA, which may have no adequate level of protection for the processing of personal data.

By clicking “Accept all”, you consent to the storage of cookies and the processing of personal data for these purposes, including any transfers to third countries. By clicking on “Decline all”, you do not give your consent and we will only store cookies that are necessary for our website. You can customize the cookies we store on your device or change your selection at any time - thus also revoking your consent with effect for the future - under “Manage Cookies”, or “Cookie Settings” at the bottom of the page. You can find further information in our Privacy Policy.
Accept all
Decline all
Manage cookies
✕

Privacy Preference Center

With your consent, we and third-party providers use cookies and similar technologies on our website to analyse your use of our site for market research or advertising purposes ("analytics and marketing") and to provide you with additional functions (“functional”). This may result in the creation of pseudonymous usage profiles and the transfer of personal data to third countries, including the USA, which may have no adequate level of protection for the processing of personal data. Please choose for which purposes you wish to give us your consent and store your preferences by clicking on “Accept selected”. You can find further information in our Privacy Policy.

Accept all cookies

Manage consent preferences

Essential cookies are strictly necessary to provide an online service such as our website or a service on our website which you have requested. The website or service will not work without them.

Performance cookies allow us to collect information such as number of visits and sources of traffic. This information is used in aggregate form to help us understand how our websites are being used, allowing us to improve both our website’s performance and your experience.

Google Analytics

Google Ads

Bing Ads

Facebook

LinkedIn

Quora

Hotjar

Reddit

Functional cookies collect information about your preferences and choices and make using the website a lot easier and more relevant. Without these cookies, some of the site functionality may not work as intended.

HubSpot

Social media cookies are cookies used to share user behaviour information with a third-party social media platform. They may consequently effect how social media sites present you with information in the future.

Accept selected