Executing query and insert operations using a Java client

In this recipe, we will look at executing the query and insert operations using the Java client for MongoDB. Unlike the Python programming language, Java code snippets cannot be executed from an interactive interpreter, and thus we will be having some unit test cases already implemented, whose relevant code snippets will be shown and explained.

Getting ready

For this recipe, we will start a standalone instance. Refer to the Installing single node MongoDB recipe from Chapter 1, Installing and Starting the Server for instructions on how to start the server.

The next step is to download the Java project, mongo-cookbook-javadriver, from the Packt website. This recipe uses a JUnit test case to test out various features of the Java client. In this whole process, we will use some of the most common API calls and thus learn to use them.

How to do it…

To execute the test case, one can either import the project in an IDE-like Eclipse and execute the test case or execute the test case from the command prompt using Maven.

The test case that we will execute for this recipe is com.packtpub.mongo.cookbook.MongoDriverQueryAndInsertTest.

  1. If you are using an IDE, open this test class and execute it as a JUnit test case.
  2. If you are planning to use Maven to execute this test case, go to the command prompt, change the directory at the root of the project, and execute the following to execute this single test case:
    $ mvn -Dtest=com.packtpub.mongo.cookbook.MongoDriverQueryAndInsertTest test
    

Everything should get executed fine and the test case should succeed if the Java SDK and Maven are properly set up and the MongoDB server is up and running and listening to port 27017 for the incoming connections.

How it works…

We will now open the test class that we executed and see some of the important API calls in the test method. The super class of our test class is com.packtpub.mongo.cookbook.AbstractMongoTest.

We start by looking at the getClient method in this class. The client instance that has been created is an instance of the com.mongodb.MongoClient type. There are several overloaded constructors for this class; however, we use the following to instantiate the client:

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

Another method to look at is getJavaDriverTestDatabase in the same abstract class that gets us the database instance. This instance is synonymous to the implicit variable db in the shell. Here in Java, this class is an instance of the com.mongodb.DB type. We get an instance of this DB class by invoking the getDB() method on the client instance. In our case, we want the DB instance for the javaDriverTest database, which we get as follows:

getClient().getDB("javaDriverTest");

Once we get the instance of com.mongodb.DB, we use it to get the instance of com.mongodb.DBCollection, which would be used to perform various operations—find and insert—on the collection. The getJavaTestCollection method in the abstract test class returns one instance of DBCollection. We get an instance of this class for the javaTest collection by invoking the getCollection() method on com.mongodb.DB as follows:

getJavaDriverTestDatabase().getCollection("javaTest")

Once we get an instance of DBCollection, we are now ready to perform the operations on it. In the scope of this recipe, it is limited to the find and insert operations.

Now, we open the main test case class, com.packtpub.mongo.cookbook.MongoDriverQueryAndInsertTest. Open this class in an IDE or a text editor. We will look at the methods in this class. The first method that we will look at is findOneDocument. Here, the line of our interest is the one that queries for the document with the value of _id as 3: collection.findOne(new BasicDBObject("_id", 3)).

This method returns an instance of com.mongodb.DBObject, which is a key value map returning the fields of a document as a key and the value of this corresponding key. For instance, to get the value of _id from the returned DBObject instance, we invoke result.get("_id") on the returned result.

Our next method to inspect is getDocumentsFromTestCollection. This test case executes a find operation on the collection and gets all the documents in it. The collection.find() call executes the find operation on the instance of DBCollection. The return value of the find operation is com.mongodb.DBCursor. An important point to note is that invoking the find operation itself doesn't execute the query but just returns the instance of DBCursor. This is an inexpensive operation that doesn't consume server-side resources. The actual query gets executed on the server side only when the hasNext or next method is invoked on the DBCursor instance. The hasNext() method is used to check if there are more results and the next() method is used to navigate to the next DBObject instance in the result. An example usage of the DBCursor instance returned to iterate through the results is as follows:

while(cursor.hasNext()) {
  DBObject object = cursor.next();
  //Some operation on the returned object to get the fields and
  //values in the document
}

We now look at two methods, withLimitAndSkip and withQueryProjectionAndSort. These methods show us how to sort, limit the number of results, and skip a number of initial results. As we can see, the sort, limit, and skip methods are chained to each other:

DBCursor cursor = collection
        .find(null)
        .sort(new BasicDBObject("_id", -1))
        .limit(2)
        .skip(1);

All these methods return an instance of DBCursor itself, which allows us to chain the calls. These methods are defined in the DBCursor class, which changes certain states according to the operation that they perform in the instance and has return this at the end of the method to return the same instance.

Remember that the actual operation is invoked on the server only on invoking the hasNext or next method on DBCursor. Invoking any method such as sort, limit, and skip after the execution of the query on the server will throw java.lang.IllegalStateException.

We used two variants of the find method. One accepts one parameter for the query to be executed and one accepts two parameters—the first one for the query and the second is another DBObject, which is used for projection that will return only a selected set of fields from the document in the result.

For instance, the following query from the withQueryProjectionAndSort method of the test case selects all the documents as the first argument as null and the returned DBCursor will have documents containing just one field called value:

DBCursor cursor = collection
      .find(null, new BasicDBObject("value", 1).append("_id", 0))
      .sort(new BasicDBObject("_id", 1));

The _id field is to be explicitly set to 0, or else it will be returned by default.

Finally, we look at two more methods in the test case, insertDataTest and insertTestDataWithWriteConcern. We use a couple of variants of the insert method in these two methods. All insert methods are invoked on the DBCollection instance and return an instance, com.mongodb.WriteResult. The result can be used to get the error that occurred during the write operation by invoking the getLastError() method, the number of documents inserted using the getN() method, and the write concern for the operation among the few operations. Refer to the Javadoc of the MongoDB API for more detail on the methods. The two insert operations that we did are as follows:

collection.insert(new BasicDBObject("value", "Hello World"));

collection.insert(new BasicDBObject("value", "Hello World"), WriteConcern.JOURNALED);

Both of these accept a DBObject instance for the document to be inserted as the first parameter. The second method allows us to provide the write concern to be used for the write operation. There are insert methods in the DBCollection class that allow bulk insert as well. Refer to the Javadocs for more details on various overloaded versions of the insert method.

See also…

The Javadocs for the current version of the MongoDB driver can be found at https://api.mongodb.org/java/current/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset