Book Image

MongoDB Cookbook

By : Amol Nayak
Book Image

MongoDB Cookbook

By: Amol Nayak

Overview of this book

<p>MongoDB is a high-performance and feature-rich NoSQL database that forms the backbone of numerous complex development systems. You will certainly find the MongoDB solution you are searching for in this book.</p> <p>Starting with how to initialize the server in three different modes with various configurations, you will then learn a variety of skills including the basics of advanced query operations and features in MongoDB and monitoring and backup using MMS. From there, you can delve into recipes on cloud deployment, integration with Hadoop, and improving developer productivity. By the end of this book, you will have a clear idea about how to design, develop, and deploy MongoDB.</p>
Table of Contents (17 chapters)
MongoDB Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Connecting to the replica set to query and insert data from a Java client


In this recipe, we will demonstrate how to connect to a replica set using a Java client and execute queries and insert data using the Java client for MongoDB. We will also see how the client would automatically failover to another member in the replica set should a primary member goes down.

Getting ready

We first need to take a look at the Connecting to a single node from a Java client recipe, as it contains all the prerequisites and steps to set up Maven and other dependencies. As we are dealing with a Java client for replica sets, a replica set must be up and running. Refer to the Starting multiple instances as part of a replica set recipe for details on how to start the replica set.

How to do it…

Let's take a look at the steps in detail:

  1. First, we need to write/copy the following piece of code (this Java class is also available for download from the book's site):

    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 com.mongodb.ServerAddress;
    
    import java.util.Arrays;
    
    /**
     *
     */
    public class ReplicaSetMongoClient {
    
        /**
         * Main method for the test client connecting to the replica set.
         * @param args
         */
        public static final void main(String[] args) throws Exception {
            MongoClient client = new MongoClient(
                    Arrays.asList(
                            new ServerAddress("localhost", 27000),
                            new ServerAddress("localhost", 27001),
                            new ServerAddress("localhost", 27002)
                    )
            );
            DB testDB = client.getDB("test");
            System.out.println("Dropping replTest collection");
            DBCollection collection = testDB.getCollection("replTest");
            collection.drop();
            DBObject object = new BasicDBObject("_id", 1).append("value", "abc");
            System.out.println("Adding a test document to replica set");
            collection.insert(object);
            System.out.println("Retrieving document from the collection, this one comes from primary node");
            DBObject doc = collection.findOne();
            showDocumentDetails(doc);
            System.out.println("Now Retrieving documents in a loop from the collection.");
            System.out.println("Stop the primary instance manually after few iterations");
            for(int i = 0 ; i < 20; i++) {
                try {
                    doc = collection.findOne();
                    showDocumentDetails(doc);
                } catch (Exception e) {
                    //Ignoring or log a message
                }
                Thread.sleep(5000);
            }
        }
    
        /**
         *
         * @param obj
         */
        private static void showDocumentDetails(DBObject obj) {
            System.out.printf("_id: %d, value is %s\n", obj.get("_id"), obj.get("value"));
        }
    }
  2. Connect to any of the nodes in the replica set, say to localhost:27000, and, from the shell, execute rs.status(). Take a note of the primary instance in the replica set and connect to it from the shell if localhost:27000 is not a primary node. Now, switch to the admin database as follows:

    repSetTest:PRIMARY>use admin
    
  3. Now, execute the preceding program from the operating system shell as follows:

    $ mvn compile exec:java -Dexec.mainClass=com.packtpub.mongo.cookbook.ReplicaSetMongoClient
    
  4. Shut down the primary instance by executing the following command on the Mongo shell connected to the primary node:

    repSetTest:PRIMARY> db.shutdownServer()
    
  5. Watch the output on the console where the com.packtpub.mongo.cookbook.ReplicaSetMongoClient class is executed using Maven.

How it works…

An interesting thing to observe is how we instantiate a MongoClient instance. It is done as follows:

MongoClient client = new MongoClient(Arrays.asList(new ServerAddress("localhost", 27000),new ServerAddress("localhost", 27001),new ServerAddress("localhost", 27002)));

The constructor takes a list of com.mongodb.ServerAddress. This class has a lot of overloaded constructors, but we chose to use the one that takes the hostname and port number. Here. we provided all the server details in a replica set as a list. We haven't mentioned what the primary node is and what the secondary nodes are. The MongoClient class is intelligent enough to figure this out and connect to the appropriate instance. The list of servers provided is called the seed list. It need not contain an entire set of servers in a replica set, though the objective is to provide as much as we can. The MongoClient class will figure out all the server details from the provided subset. For example, if the replica set is of five nodes but we provide only three servers, it still works fine. On connecting with the provided replica set servers, the client will query them to get the replica set metadata and figure out the rest of the provided servers in the replica set. In the preceding case, we instantiated the client with three instances in the replica set. If the replica set has five members, instantiating the client with just three of them as we did earlier is still good enough, and the remaining two instances will be automatically discovered.

Next, we will start the client from the command prompt using Maven. Once the client is running in the loop to find one document, we will bring down the primary instance. We will see something like the following output on the console:

_id: 1, value is abc
Now, retrieving documents in a loop from the collection.
Stop the primary instance manually after a few iterations:
_id: 1, value is abc
_id: 1, value is abc
Nov 03, 2013 5:21:57 PM com.mongodb.ConnectionStatus$UpdatableNode update
WARNING: Server seen down: Amol-PC/192.168.1.171:27002
java.net.SocketException: Software caused connection abort: recv failed
        at java.net.SocketInputStream.socketRead0(Native Method)

        at java.net.SocketInputStream.read(SocketInputStream.java:150)

WARNING: Primary switching from Amol-PC/192.168.1.171:27002 to Amol-PC/192.168.1.171:27001
_id: 1, value is abc

As we can see, the query in the loop was interrupted when the primary node went down. The client, however, switched to the new primary node seamlessly, well, nearly seamlessly, as the client might have to catch an exception and retry the operation after a predetermined interval has elapsed.