Book Image

MongoDB Cookbook - Second Edition - Second Edition

By : Amol Nayak
Book Image

MongoDB Cookbook - Second Edition - Second Edition

By: Amol Nayak

Overview of this book

MongoDB is a high-performance and feature-rich NoSQL database that forms the backbone of the systems that power many different organizations – it’s easy to see why it’s the most popular NoSQL database on the market. Packed with many features that have become essential for many different types of software professionals and incredibly easy to use, this cookbook contains many solutions to the everyday challenges of MongoDB, as well as guidance on effective techniques to extend your skills and capabilities. This book starts with how to initialize the server in three different modes with various configurations. You will then be introduced to programming language drivers in both Java and Python. A new feature in MongoDB 3 is that you can connect to a single node using Python, set to make MongoDB even more popular with anyone working with Python. You will then learn a range of further topics including advanced query operations, monitoring and backup using MMS, as well as some very useful administration recipes including SCRAM-SHA-1 Authentication. Beyond that, you will also find recipes on cloud deployment, including guidance on how to work with Docker containers alongside MongoDB, integrating the database with Hadoop, and tips for improving developer productivity. Created as both an accessible tutorial and an easy to use resource, on hand whenever you need to solve a problem, MongoDB Cookbook will help you handle everything from administration to automation with MongoDB more effectively than ever before.
Table of Contents (17 chapters)
MongoDB Cookbook Second Edition
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Connecting to a single node using a Java client


This recipe is about setting up the Java client for MongoDB. You will repeatedly refer to this recipe while working on others, so read it very carefully.

Getting ready

The following are the prerequisites for this recipe:

  • Java SDK 1.6 or above is recommended.

  • Use the latest version of Maven available. Version 3.3.3 was the latest at the time of writing this book.

  • MongoDB Java driver version 3.0.1 was the latest at the time of writing this book.

  • Connectivity to the Internet to access the online maven repository or a local repository. Alternatively, you may choose an appropriate local repository accessible to you from your computer.

  • The Mongo server is up and running on localhost and port 27017. Take a look at the first recipe, Installing single node MongoDB, and start the server.

How to do it…

  1. Install the latest version of JDK from https://www.java.com/en/download/ if you don't already have it on your machine. We will not be going through the steps to install JDK in this recipe, but before moving on with the next step, JDK should be present.

  2. Maven needs to be downloaded from http://maven.apache.org/download.cgi. We should see something similar to the following image on the download page. Choose the binaries in a .tar.gz or .zip format and download it. This recipe is executed on a machine running on the Windows platform and thus these steps are for installation on Windows.

  3. Once the archive has been downloaded, we need to extract it and put the absolute path of the bin folder in the extracted archive in the operating system's path variable. Maven also needs the path of JDK to be set as the JAVA_HOME environment variable. Remember to set the root of your JDK as the value of this variable.

  4. All we need to do now is type mvn -version on the command prompt, and if we see the output that begins with something as follows, we have successfully set up maven:

    > mvn -version
    
  5. At this stage, we have maven installed, and we are now ready to create our simple project to write our first Mongo client in Java. We start by creating a project folder. Let's say that we create a folder called Mongo Java. Then we create a folder structure, src/main/java, in this project folder. The root of the project folder then contains a file called pom.xml. Once this folder's creation is done, the folder structure should look as follows:

          Mongo Java      
          +--src  
          |     +main
          |         +java
          |--pom.xml
  6. We just have the project skeleton with us. We shall now add some content to the pom.xml file. Not much is needed for this. The following content is all we need in the pom.xml file:

    <project>
      <modelVersion>4.0.0</modelVersion>
      <name>Mongo Java</name>
      <groupId>com.packtpub</groupId>
      <artifactId>mongo-cookbook-java</artifactId>
      <version>1.0</version>    <packaging>jar</packaging>
      <dependencies>
        <dependency>
          <groupId>org.mongodb</groupId>
          <artifactId>mongo-java-driver</artifactId>
          <version>3.0.1</version>
        </dependency>
      </dependencies>
    </project>
  7. We finally write our Java client that will be used to connect to the Mongo server and execute some very basic operations. The following is the Java class in the src/main/java location in the com.packtpub.mongo.cookbook package, and the name of the class is FirstMongoClient:

    package com.packtpub.mongo.cookbook;
    
    import com.mongodb.BasicDBObject;
    import com.mongodb.DB;
    import com.mongodb.DBCollection;
    import com.mongodb.DBObject;
    import com.mongodb.MongoClient;
    
    import java.net.UnknownHostException;
    import java.util.List;
    
    /**
     * Simple Mongo Java client
     *
     */
    public class FirstMongoClient {
    
        /**
         * Main method for the First Mongo Client. Here we shall be connecting to a mongo
         * instance running on localhost and port 27017.
         *
         * @param args
         */
        public static final void main(String[] args) 
    throws UnknownHostException {
            MongoClient client = new MongoClient("localhost", 27017);
            DB testDB = client.getDB("test");
            System.out.println("Dropping person collection in test database");
            DBCollection collection = testDB.getCollection("person");
            collection.drop();
            System.out.println("Adding a person document in the person collection of test database");
            DBObject person = 
    new BasicDBObject("name", "Fred").append("age", 30);
            collection.insert(person);
            System.out.println("Now finding a person using findOne");
            person = collection.findOne();
            if(person != null) {
                System.out.printf("Person found, name is %s and age is %d\n", person.get("name"), person.get("age"));
            }
            List<String> databases = client.getDatabaseNames();
            System.out.println("Database names are");
            int i = 1;
            for(String database : databases) {
                System.out.println(i++ + ": " + database);
            }
      System.out.println("Closing client");
            client.close();
        }
    }
  8. It's now time to execute the preceding Java code. We will execute it using maven from the shell. You should be in the same directory as pom.xml of the project:

    mvn compile exec:java -Dexec.mainClass=com.packtpub.mongo.cookbook.FirstMongoClient
    

How it works…

These were quite a lot of steps to follow. Let's look at some of them in more detail. Everything up to step 6 is straightforward and doesn't need any explanation. Let's look at step 7 onwards.

The pom.xml file that we have here is pretty simple. We defined a dependency on mongo's Java driver. It relies on the online repository, repo.maven.apache.org, to resolve the artifacts. For a local repository, all we need to do is define the repositories and pluginRepositories tags in pom.xml. For more information on maven, refer to the maven documentation at http://maven.apache.org/guides/index.html.

For the Java class, the org.mongodb.MongoClient class is the backbone. We first instantiate it using one of its overloaded constructors giving the server's host and port. In this case, the hostname and port were not really needed as the values provided are the default values anyway, and the no-argument constructor would have worked well too. The following code snippet instantiates this client:

MongoClient client = new MongoClient("localhost", 27017);

The next step is to get the database, in this case, test using the getDB method. This is returned as an object of the com.mongodb.DB type. Note that this database might not exist, yet getDB will not throw any exception. Instead, the database will get created whenever we add a new document to the collection in this database. Similarly, getCollection on the DB object will return an object of the com.mongodb.DBCollection type representing the collection in the database. This too might not exist in the database and will get created on inserting the first document automatically.

The following two code snippets from our class show you how to get an instance of DB and DBCollection:

DB testDB = client.getDB("test");
DBCollection collection = testDB.getCollection("person");

Before we insert a document, we will drop the collection so that even upon multiple executions of the program, we will have just one document in the person collection. The collection is dropped using the drop() method on the DBCollection object's instance. Next, we create an instance of com.mongodb.DBObject. This is an object that represents the document to be inserted into the collection. The concrete class used here is BasicDBObject, which is a type of java.util.LinkedHashMap, where the key is String and the value is Object. The value can be another DBObject too, in which case, it is a document nested within another document. In our case, we have two keys, name and age, which are the field names in the document to be inserted and the values are of the String and Integer types, respectively. The append method of BasicDBObject adds a new key value pair to the BasicDBObject instance and returns the same instance, which allows us to chain the append method calls to add multiple key value pairs. This created DBObject is then inserted into the collection using the insert method. This is how we instantiated DBObject for the person collection and inserted it into the collection as follows:

DBObject person = new BasicDBObject("name", "Fred").append("age", 30);
collection.insert(person);

The findOne method on DBCollection is straightforward and returns one document from the collection. This version of findOne doesn't accept DBObject (which otherwise acts as a query executed before a document is selected and returned) as a parameter. This is synonymous to doing db.person.findOne() from the shell.

Finally, we simply invoke getDatabaseNames to get a list of databases' names in the server. At this point of time, we should at least be having test and the local database in the returned result. Once all the operations are complete, we close the client. The MongoClient class is thread-safe and generally one instance is used per application. To execute the program, we use the maven's exec plugin. On executing step 9, we should see the following lines toward the end in the console:

[INFO] [exec:java {execution: default-cli}]
--snip--
Dropping person collection in test database
Adding a person document in the person collection of test database
Now finding a person using findOne
Person found, name is Fred and age is 30
Database names are
1: local
2: test
INFO: Closed connection [connectionId{localValue:2, serverValue:2}] to localhost:27017 because the pool has been closed.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Tue May 12 07:33:00 UTC 2015
[INFO] Final Memory: 22M/53M
[INFO] ------------------------------------------------------------------------