How to run node.js with MongoDB

Posted on August 31st, 2019

Many of today’s web applications use node.js in conjunction with MongoDB to store and access data on the backend server. Not only does node.js excel in ease of access to non-relational databases like MongoDB, but brings scalability and speed to the server side of your app.

With the growing popularity of MEAN (MongoDB, Express, Angular and Node) and MERN (MongoDB, Express, React and Node) stacks, proficiency in CRUD operations on NoSQL databases like MongoDB is something every app developer should have. Fortunately, it’s fairly simple and easy, especially with the delicious tutorial we’ve prepared just for you.

How can a tutorial be delicious? Is using Node.js with MongoDB really simpler than ordering dinner? Keep reading to find out!

Before we start cooking, let’s get to know our ingredients.

Node.js

Node.js is a JavaScript runtime environment for the back-end of your application. Based on Google’s V8 JavaScript engine, Node.js includes numerous components and features necessary for web app implementation.

One of the main advantages of Node.js is its scalability thanks to its event-driven asynchronous engine. Since it continues working on other tasks in the queue instead of waiting for the client to respond, it can perform many more operations in parallel – and thus faster.

In addition, Node.js supports the quick installation of third party packages and modules using the npm tool, which we will also use in this tutorial to install MongoDB.

MongoDB

MongoDB is an open source non-relational database that stores the data in the form of collections and documents. Designed with agility and scalability in mind, MongoDB brings together the rich features of relational databases and speed of key-value stores

Instead of storing data in rows and columns (as relational databases do), MongoDB stores the JSON documents in the form of collections with dynamic schemas. Storing all related information together makes querying faster, and since MongoDB was also designed to be used asynchronously, it makes for an ideal repository for the data of Node.js applications.

In this tutorial, we’ll be installing MongoDB on your local machine, but for production purposes, you might want to use the MongoDB Atlas cloud database service.

Environment Setup

If you have yet to do so, download and install MongoDB on your machine using the file that matches your OS and processor. Once installed, run MongoDB from the command prompt of your operating system. If you use the default settings, the port on which MongoDB will listen will be 27017.

Now that we have our ingredients ready, it’s time to get cooking and introduce them to one another.

1. Installing MongoDB npm

Regardless of whether you have a Node.js project you’re looking to connect to a MongoDB database or you are creating a new project, you’ll need to install the MongoDB package using the Node.js Package Manager (npm). To do that, open a terminal window in your IDE of choice, and type:

npm install -g mongodb

This will install mongodb as a global library, so all your Node.js projects will have access to it and be able to use it.

2. Connecting to MongoDB

With your kitchen (the backend) and ingredients in place, it’s time to mix those flavors. Create a file in your project folder named server.js. As the name implies, this will be your server, and it will be bringing out the dishes (or any other kind of data) you’ll have in your MongoDB database.

To allow Node.js access to MongoDB as a client, you’ll need to enter the requirement in your server.js file.

const {MongoClient} = require('mongodb');

To connect Node.js to the actual MongoDB database server running locally on your machine, we’ll need to specify its URL. If you didn’t make any changes in the setup process, the URL should be:

const url = 'mongodb://localhost:27017/';

CRUD Operations on MongoDB with Node.js

With the above lines in our server.js file, we now have access to all the CRUD functions of mongoClient. CRUD stands for Create, Read, Update and Delete – the basic functions you will be applying on your database. 

So let’s start with the first: Creation. 

1. Creating a MangoDB Database & Adding Documents to Collections

In our mouth-watering Dinner project, we’ll be creating a database of dishes we could order. To start, we’ll be adding a document (a dish) into a collection named dishes in a database that we’ll (fairly unoriginally) name dishesdb

Now comes the neat part about cooking with MongoDB and Node.js – you don’t have to declare the names of the database and collection in advance. If they do not exist when we call them, they will be created when we insert a document into a collection.

To insert delicious dishes (documents) into our menu (collection), we can use one of two methods. To add a single dish, we’ll use insertOne(), and to add a number of dishes at once we’ll be using insertMany().

The code below, once executed, will attempt to add a single dish, “Greens Fava Salad”, to the collection dishes in the database dishesdb. The variable dbo is used to refer to our database (dishesdb), and in it we’re creating a collection named dishes using the collection() method.

Since we won’t be using a frontend for the purpose of this tutorial, we’ll be tracking what happens on the server through terminal output. To view the results of script execution, we’ll use console.log() and specify a success message to display – 1 document inserted into collection dishes.

Here’s a function to insert one single dish into our database, dishesdb:

async function createOne(dbName, collectionName, newdish) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   await client.db(dbName).collection(collectionName).insertOne(newdish);
   console.log("1 document inserted into collection dishes");
   client.close();
 }

Now all we need to do is define a new dish and then call the function:

let newdish = { innerId: 1, title: 'Greens Fava Salad', description: 'Tossed greens with citrus dressing.', price: '$10'}; await createOne('dishesdb', 'dishes', newdish);

Note that it’s important to close the database connection at the completion of every interaction using client.close(). Leaving connections open can be a security vulnerability as well as cause errors and malfunctions. 

In addition, if you want to simplify your code and improve performance you can use this method to share a single database connection across your entire codebase.

To test it out add the code above to your server.js file and run node server.js in a terminal. If all goes well, you should receive the message – 1 document inserted into collection dishes.

Inserting multiple items into your collection is very similar. You simply need to use insertMany() instead of insertOne()

Here’s a function to insert many dishes into our database, dishesdb:

async function createMany(dbName, collectionName, mydishes) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const res = await client.db(dbName).collection(collectionName).insertMany(mydishes);
   console.log("Number of dishes added:", res.insertedCount);
   client.close();
 }

Now all we need to do is define a few dishes and then call the function:

let mydishes = [
    { innerId: 2, title: 'Seasonal Pumpkin Soup', description: 'Hot and filling Thai Pumpkin Soup.', price: '$13'},
    { innerId: 3, title: 'Fresh Vegetables', description: 'Freshly cut vegetables with olive oil and zest.', price: '$10'},
    { innerId: 4, title: 'New York Cheesecake', description: 'Delicious Cheesecake with an accompaniment of seasonal fruits.', price: '$20'},
    { innerId: 5, title: 'Chocolate Donut', description: 'Our chef' s recipe for a chocolate donut.', price: '$15'},
    { innerId: 6, title: 'Watermelon Cocktail', description: 'A light alcoholic cocktail to cleanse your pallet.', price: '$17'}
    ];
await createMany('dishesdb', 'dishes', mydishes);

As you can see, in addition to the title and description of each dish, we also added our own unique identifiers for the dishes / documents (innerId) to prevent confusion between the identification scheme of our Dinner menu and the MongoDB index for documents.

Now that we have some documents in a collection stored in the database, we can read them.

2. Reading from a MongoDB Database

To read from the DB we can use find() and findOne(). To get all the content of a collection, we can use find() without any qualifying queries.

Here’s a function using find() to locate all of the documents of collection collectionName in database dbName.

async function locateAll(dbName, collectionName) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const result = await client.db(dbName).collection(collectionName).find({}).toArray();
   console.log(result);
   client.close();
}

Running this function for database dishesdb and collection dishes looks like this:

await locateAll('dishesdb', 'dishes');

The result will be all 6 dishes that are currently listed in collection ‘dishes’.

We can make the search more specific by adding a query to the find() function. 

For example, here is a function that accepts a specific query in addition to the dbName and collectionName

async function locateByQuery(dbName, collectionName, myQuery) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const result = await client.db(dbName).collection(collectionName).find(myQuery).toArray();
   console.log(result);
   client.close();
 }

Here is how we define a query to locate all the dishes priced at $10 and then call the function.

let myquery = { price: '$10' }; await locateByQuery('dishesdb', 'dishes', myquery);<br>

If we’re looking to find only one specific document we can use findOne(). It works pretty much like find() except it will always return a single object – the first document to match the query. So if we change the above code to findOne() instead of find(), we’ll only get the first item on our menu to cost $10.

Here’s the function locateOneByQuery() that does exactly that:

async function locateOneByQuery(dbName, collectionName, myQuery) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const result = await client.db(dbName).collection(collectionName).findOne(myQuery);
   console.log(result);
   client.close();
 }

3. Updating Documents in a MongoDB Database

The next operation in CRUD is Update and as the name implies, it allows us to update documents in our MangoDB database collections. 

Much like with creating and reading, updates to documents can be done in singles or in bulk. To update one document we can use updateOne() and updateMany() to change values in a number of documents at once.

With updateMany(), you can alter the values of multiple documents that match a query. updateOne()  will update the first document to match it in our collection.

Here’s a function for updating one document that expects the dbName and collectionName in addition to the query and the new values: 

async function renewOneByQuery(dbName, collectionName, myQuery, newValue)
 {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const res = await client.db(dbName).collection(collectionName).updateOne(myQuery, newValue);
   console.log("number of documents updated:", res.result.nModified);
   client.close();
 }

For example, let’s make our soup extra-attractive by updating the name and description. From ‘Seasonal Pumpkin Soup’, we’ll change the name to ‘Autumn Pumpkin Soup’ and include some details about the soup’s unique properties in the description.

The code to do that would look like this:

let newQuery = { title: 'Seasonal Pumpkin Soup' };
    let newValue = { $set: {title: 'Autumn Pumpkin Soup', description: 'Hot and filling Bengali Pumpkin Soup.' }};
    await renewOneByQuery('dishesdb', 'dishes', newQuery, newValue);

With such appetizing names and descriptions, our dishes seem underpriced, wouldn’t you agree? So let’s raise some prices.

In order to change the price of all dishes costing ‘$10’ to ‘$20’, let’s create a function that updates many documents at once based on our given query. The function code would look like this:

async function renewManyByQuery(dbName, collectionName, myQuery, newValue) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const res = await client.db(dbName).collection(collectionName).updateMany(myQuery, newValue);
   console.log("number of documents updated:", res.result.nModified);
   client.close();
 }

The code defining the query and new values would look like this:

  let newQuery = { price: '$10' };
    let newValue = { $set: {price: '$20' }};
    await renewManyByQuery('dishesdb', 'dishes', newQuery, newValue);

This will update the price on dishes 1 and 3 from $10 to $20.

4. Deleting Documents from a MongoDB Database

The D in CRUD stands for Deletion, so this is the last function we’ll look at. As with creating, reading and updating, we can delete one document or multiple ones with deleteOne() and deleteMany().

To delete a single item from our menu, in this case the item with the innerId value 1, we’ll first add this function to our server.js file:

async function removeOneByQuery(dbName, collectionName, myQuery) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const obj  = await client.db(dbName).collection(collectionName).deleteOne(myQuery);
   console.log("document deleted:", obj.result.n);
   client.close();
 }

Then we’ll call the function like this:

    let myQuery = { innerId: 1 }; await removeOneByQuery('dishesdb', 'dishes', myQuery);<br>

Just like deleting one document we can delete many. Here’s the function to delete all documents that fit the given query:

async function removeManyByQuery(dbName, collectionName, myQuery) {
   const client = await MongoClient.connect(url, {useNewUrlParser: true});
   const obj  = await client.db(dbName).collection(collectionName).deleteMany(myQuery, newValue);
   console.log("document(s) deleted:", obj.result.n);
   client.close();
 }

In this case we’ll call the function without specifying any query so calling the function will delete ALL documents in the dishes collection:

await removeManyByQuery('dishesdb', 'dishes', {});

With these commands, we’ve covered pretty much all you need to know to use MongoDB with Node.js.

The next step (once you’ve grabbed something quick to eat to satisfy the munchies we just gave you) is adding a frontend and Express.js to interconnect your app with the backend we just created. With those in place, you’ll be able to expand the Dinner we cooked into a web app with visuals and UX to make a user salivate.

How to set up PostgreSQL to work with Java

Posted on August 13th, 2019

Postgres supports the Java language but working with Java in Postgres is easier with the Java Database Connectivity (JDBC) interface. Below is an introduction to the Java Database Connectivity interface and provide you with a few code tips to get you started. 

What Is PostgreSQL and Why It’s Cool Again

PostgreSQL is a highly popular object-oriented relational database management system (RDBMS). It is open-source and free, which makes it very popular with developers. The platform supports relational and non-relational queries by supporting JSON. However, one of the characteristics of Postgres is its emphasis on compliance with SQL standards. The database is designed to handle a range of workloads from single machines to data warehouses

Postgres main features include:

  • Compatibility with major OS—supports Windows, Linux, Mac OS, Solaris. 
  • Main programming languages support—such as C/C++, Phyton, Go and Java.
  • Multiversion Concurrency Control—this is the main Postgres feature that allows several readers and writers to access and work in the same database at the same time. 
  • High compliance—complies with 169 features of the SQL standard. 
  • Dynamic community—develop and release extensions regularly. 

Despite being one of the oldest database systems on the market, PostgreSQL ranks as one of the most popular Database Management Systems amongst developers and database administrators. Some of the reasons for its popularity are: 

  • Free to use—you can store unlimited data without functionality constraints and no distribution restrictions. 
  • Avoids vendor lock-in—since allows the distribution, there are an array of companies providing services for Postgres, thus eliminating vendor lock-in. 
  • Extensible—the Postgres community takes advantage of the easy extensions to add features to the database almost constantly. This flexibility allows users that need a particular feature to just write an extension for it. 

Postgres extensions make it possible for users to adapt the database for their needs without changing the core database. In addition, some cool PostgreSQL features include the ability to create your own data types and XML data queries. The streaming replication makes postgres backup solutions very attractive. 

PostgreSQL allows to run NoSQL queries by supporting JavaScript Object Notation (JSON) which is a lightweight format for storing and transporting data.  Postgres supports Java through a Java Database Connectivity (JDBC) which allows Java programs to connect to a PostgreSQL database using standard Java code. Read on to learn how to set up Postgres to work with Java. 

Setting Up PostgreSQL to Work with Java

Before we can start using PostgreSQL in Java programs we need to set up JDBC and Java on the machine. 

  1. Download and install the latest version of Postgres JDBC from the Postgres repository.  
  2. You should add the downloaded .jar file in your classpath or use it with the -classpath option.
  3. The PostgreSQL server must be configured to allow TCP/IP connections, then verify users are allowed to connect to the server by setting up client authentication. 
  4. Creating a database that will be accessed through JDBC needs a correct encoding of the data, meaning you should use the UNICODE encoding as a default to avoid discrepancies. 

Initializing the Driver implies:

  • Importing the JDBC—using import java.sql.*;
  • Loading the Driver—with the new versions the drivers will be loaded by the JVM when the application connects to PostgreSQL. 

The Postgresql Java Jdbc Interface—What It Is and Basic Commands

As mentioned above, JDBC is the core API of Java that provides a standard interface to SQL-compliant databases, especially PostgreSQL. We covered how to set up the JDBC driver and some considerations when creating the database. But how do we connect to an existing database? The following example of Java code, from the out code library, demonstrates how to connect to a postrgresql database instance using Amazon Web Services:

 public void donothing() throws SQLException, ClassNotFoundException
{
  Class.forName("org.postgresql.Driver");
  String url = "jdbc:postgresql://localhost/test?user=fred&password=secret&ssl=true";
  Connection conn = DriverManager.getConnection(url);
  // Do stuff here
  conn.close();
}

Querying data from a table in the PostgreSQL database using JDBC API
Once you establish a database connection to the PostgreSQL server you need to create a statement object, which represents a SQL statement. There are three kinds of Statement objects:

  • Statement—you implement a simple Statement without parameters
  • PreparedStatement—a subclass, you can use it to add the parameters to SQL statements. 
  • CallableStatement—you can use it to extend a PreparedStatement used to execute a stored procedure. 

After you create the Statement object, you can execute the query using one of these three methods:

  • Execute—this command will return true if the first object of the query is a ResultSet object. 
  • executeQuery—will return only one ResultSet object.
  • executeUpdate—you can use this method for statements such as INSERT or DELETE, as it returns the number of rows affected by the statement. 

Finally, you can use a Java cursor to call the methods of the ResultSet object, then use a try-with-resources statement. This allows you to close all three objects (ResultSet, Statement, and Connection) automatically. 

Create a Table
You can use the following Java program to create a table in an open database.
import java.sql.*;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class PostgreSQLJDBC {
   public static void main( String args[] ) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         System.out.println("Opened database successfully");
         stmt = c.createStatement();
         String sql = "CREATE TABLE COMPANY " +
            "(ID INT PRIMARY KEY     NOT NULL," +
            " NAME           TEXT    NOT NULL, " +
            " AGE            INT     NOT NULL, " +
            " ADDRESS        CHAR(50), " +
            " SALARY         REAL)";
         stmt.executeUpdate(sql);
         stmt.close();
         c.close();
      } catch ( Exception e ) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Table created successfully");
   }
}

Once the program is compiled and executed, it will display the following two lines: 

Opened database successfully
Table created successfully

Discover similar code snippet examples using java.sql.DriverManager.getConnection

Insert Operation

How we can create records on our table

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class PostgreSQLJDBC {
   public static void main(String args[]) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         c.setAutoCommit(false);
         System.out.println("Opened database successfully");
         stmt = c.createStatement();
         String sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (1, 'Paul', 32, 'California', 20000.00 );";
         stmt.executeUpdate(sql);
         sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (2, 'Allen', 25, 'Texas', 15000.00 );";
         stmt.executeUpdate(sql);
         sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );";
         stmt.executeUpdate(sql);
         sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
         stmt.executeUpdate(sql);
         stmt.close();
         c.commit();
         c.close();
      } catch (Exception e) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Records created successfully");
   }
}

Discover Similar examples with prepared statement

When the above program is compiled and executed, it will create given records in COMPANY table and will display the following two lines.

Opened database successfully
Records created successfully

Using the JDBC PostgreSQL transaction using JDBC transaction API.  

This is useful when you don’t want one SQL statement to execute unless another one completes. For example, inserting a new actor and the film that the actor leads.  Using a transaction you ensure that both statements take effect or neither does. 

The first step is to disable auto-commit mode, since Postgres treats each statement as a transaction, automatically committing it. Therefore, if you want to isolate one or more statements in a transaction, the first step is disabling auto-commit mode. You call the setAutoCommit() method of Connection by this command:

conn.setAutoCommit(false);

If you want to commit a transaction, you should call the commit method of the Connection object:

conn.commit();

Next, when you call the commit() method, you will find all the previous statements committed together as a single unit.

Rollback a transaction

Sometimes you don’t get the result of one statement that your expected. In this case, you can use the  rollback() method of the Connection object, to interrupt the current transaction, restoring values to original. 

conn.rollback();

You can learn more in this YouTube video tutorial 

The Bottom Line

Setting up the PostgreSQL JDBC interface may seem tricky. However, the latest versions of PostgreSQL have made the installation pretty straightforward by loading the driver automatically in the JVM.

Working on PostgreSQL using Java code is easier using the proprietary JDBC interface. In this article, we provided you with a brief introduction to how to install the interface and basic commands to start playing around.