MongoDB with Java

The official MongoDB Java Driver providing both synchronous and asynchronous interaction with MongoDB. Powering the drivers is a new driver core and BSON library. Core features are:

  • BSON Library – A standalone BSON library, with a new Codec infrastructure that you can use to build high-performance encoders and decoders without requiring an intermediate Map instance.
  • MongoDB Driver – An updated Java driver that includes the legacy API as well as a new generic. MongoCollection interface that complies with a new cross-driver CRUD specification.
  • MongoDB Async Driver – A new asynchronous API that can leverage either Netty or Java 7’s AsynchronousSocketChannel for fast and non-blocking IO.
  • Core driver – The MongoDB Driver and Async Driver are both built on top of a new core library, which anyone can use to build alternative or experimental high-level APIs.

 

Installation

There are two Maven artifacts available in the 3.1 release. The preferred artifact for new applications ismongodb-driver however, we still publish the legacy mongo-java-driver uber-jar. The recommended way to get started using one of the drivers in your project is with a dependency management system.

Mongo-Java-Driver (all in one dependencies – it works!): https://oss.sonatype.org/content/repositories/releases/org/mongodb/mongo-java-driver/

Mongo-driver: https://oss.sonatype.org/content/repositories/releases/org/mongodb/mongodb-driver/

 

Maven

 

MongoDB Driver

The MongoDB Driver is the updated synchronous Java driver that includes the legacy API as well as a new generic MongoCollection interface that complies with a new cross-driver CRUD specification.

<dependencies>
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongodb-driver</artifactId>
        <version>3.1.1</version>
    </dependency>
</dependencies>

You can also download the jars directly from sonatype.

Note: mongodb-driver requires the following dependencies: bson and mongodb-driver-core

Uber MongoDB Java Driver

An uber jar that contains everything you need; the BSON library, the core library and the mongodb-driver.

<dependencies>
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>3.1.1</version>
    </dependency>
</dependencies>

You can also download the jars directly from sonatype.

 

Getting Started

Make a Connection

If the database does not exist, MongoDB will create it for you. The MongoClient instance actually represents a pool of connections to the database; you will only need one instance of class MongoClient even with multiple threads.

MongoClient mongoClient = new MongoClient( "localhost" );

// or
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

// or, to connect to a replica set, with auto-discovery of the primary, supply a seed list of members
MongoClient mongoClient = new MongoClient(
  Arrays.asList(new ServerAddress("localhost", 27017),
                new ServerAddress("localhost", 27018),
                new ServerAddress("localhost", 27019)));

// or use a connection string
MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017,localhost:27018,localhost:27019");
MongoClient mongoClient = new MongoClient(connectionString);

MongoDatabase database = mongoClient.getDatabase("contactlist");

 IMPORTANT

Typically you only create one MongoClient instance for a given database cluster and use it across your application. When creating multiple instances:

  • All resource usage limits (max connections, etc) apply per MongoClient instance
  • To dispose of an instance, make sure you call MongoClient.close() to clean up resources

 

Get a Collection

To get a collection to operate upon, specify the name of the collection to the getCollection() method:

// Get a Collection
// To get a collection to operate upon, specify the name of the collection to the getCollection() method:
MongoCollection<Document> collection = database.getCollection("contactlist");

 

Insert a Document

Once you have the collection object, you can insert documents into the collection. To create the document using the Java driver, use the Document class. You can use this class to create the embedded document as well.

// Create Document
// To create the document using the Java driver, use the Document class. You can use this class to create the embedded document as well.
Document doc = new Document("name", "Empeccable")
        .append("email", "empeccable@testemail.com")
        .append("number", "(111)-111-1111")
        .append("info", new Document("x", 203).append("y", 102));

//Insert a Document
//Once you have the collection object, you can insert documents into the collection.
collection.insertOne(doc);

 

Add Multiple Documents

To add multiple documents to the collection, pass the list of documents to the insertMany() method.

//Add Multiple Documents
//To add multiple documents, you can use the insertMany() method.
List<Document> documents = new ArrayList<Document>();
for (int i = 0; i < 10; i++) {
    Document docs = new Document("name", "Empeccable" + i)
            .append("email", "empeccable" + i + "@testemail.com")
            .append("number", "(111)-111-111" + i);
    documents.add(docs);
}
//To insert these documents to the collection, pass the list of documents to the insertMany() method.
collection.insertMany(documents);

 

Count Documents in A Collection

//Count Documents in A Collection
//Now that we’ve inserted 10 documents (the 10 we did in the loop, plus the first one), we can check to see if we have them all using the count() method. The following code should print 101.
System.out.println(collection.count() + "\r\n");

 

Query the Collection

To get the first document in the collection, call the first() method on the find() operation.collection.find().first() returns the first document or null rather than a cursor. This is useful for queries that should only match a single document, or if you are interested in the first document only.

//Query the Collection
//Use the find() method to query the collection.
//Find the First Document in a Collection
//To get the first document in the collection, call the first() method on the find() operation. collection.find().first() returns the first document or null rather than a cursor. This is useful for queries that should only match a single document, or if you are interested in the first document only.
Document myDoc = collection.find().first();
System.out.println(myDoc.toJson() + "\r\n");

 NOTE

The _id element has been added automatically by MongoDB to your document and your value will differ from that shown. MongoDB reserves field names that start with “_” and “$” for internal use.

To retrieve all the documents in the collection, we will use the find() method. The find() method returns a FindIterable instance that provides a fluent interface for chaining or controlling find operations. Use the iterator() method to get an iterator over the set of documents that matched the query and iterate.

//Find All Documents in a Collection
//To retrieve all the documents in the collection, we will use the find() method. The find() method returns a FindIterable instance that provides a fluent interface for chaining or controlling find operations. Use the iterator() method to get an iterator over the set of documents that matched the query and iterate. The following code retrieves all documents in the collection and prints them out (10 documents):
MongoCursor<Document> cursor = collection.find().iterator();
try {
    while (cursor.hasNext()) {
        System.out.println(cursor.next().toJson());
    }
} finally {
    cursor.close();
}
System.out.println("\r\n");

 

Get A Single Document with a Query Filter

We can create a filter to pass to the find() method to get a subset of the documents in our collection.

//Get A Single Document with a Query Filter
//We can create a filter to pass to the find() method to get a subset of the documents in our collection.
//Use the Filters, Sorts, Projections and Updates helpers for simple and concise ways of building up queries.
myDoc = collection.find(eq("name", "Empeccable")).first();
System.out.println(myDoc.toJson() + "\r\n");

 NOTE

Use the Filters, Sorts, Projections and Updates helpers for simple and concise ways of building up queries.

 

Get a Set of Documents with a Query

We can use the query to get a set of documents from our collection.

//Get a Set of Documents with a Query
//We can use the query to get a set of documents from our collection
// now use a range query to get a larger subset
Block<Document> printBlock = new Block<Document>() {
    @Override
    public void apply(final Document document) {
        System.out.println(document.toJson());
    }
};
//Notice we use the forEach method on FindIterable which applies a block to each document and we print all documents where i > 10.
collection.find(gt("i", 10)).forEach(printBlock);

Notice we use the forEach method on FindIterable which applies a block to each document and we print all documents where i > 10.

//We could also get a range, say 8 < i <= 16
collection.find(and(gt("i", 8), lte("i", 16))).forEach(printBlock);

 

Sorting documents

We can also use the Sorts helpers to sort documents. We add a sort to a find query by calling thesort() method on a FindIterable. Below we use the exists() helper and sort descending("i")helper to sort our documents:

//Sorting documents
//We can also use the Sorts helpers to sort documents. We add a sort to a find query by calling the sort() method on a FindIterable. Below we use the exists() helper and sort descending("i") helper to sort our documents:
myDoc = collection.find(exists("i")).sort(descending("i")).first();

 

Projecting fields

Sometimes we don’t need all the data contained in a document, the Projections helpers help build the projection parameter for the find operation. Below we’ll sort the collection, exclude the _id field by using the Projections.excludeId and output the first matching document:

//Projecting fields
//Sometimes we don’t need all the data contained in a document, the Projections helpers help build the projection parameter for the find operation. Below we’ll sort the collection, exclude the _id field by using the Projections.excludeId and output the first matching document:
myDoc = collection.find().projection(excludeId()).first();

 

Aggregations

Sometimes we need to aggregate the data stored in MongoDB. The Aggregates helper provides builders for each of type of aggregation stage.

Below we’ll do a simple two step transformation that will calculate the value of i * 10. First we find all Documents where i > 0 by using the Aggregates.match helper. Then we reshape the document by using Aggregates.project in conjunction with the $multiply operator to calculate the “ITimes10” value:

//Aggregations
//Sometimes we need to aggregate the data stored in MongoDB. The Aggregates helper provides builders for each of type of aggregation stage.
//Below we’ll do a simple two step transformation that will calculate the value of i * 10. First we find all Documents where i > 0 by using the Aggregates.match helper. Then we reshape the document by using Aggregates.project in conjunction with the $multiply operator to calculate the “ITimes10” value:
collection.aggregate(asList(
                match(gt("i", 0)),
                project(Document.parse("{ITimes10: {$multiply: ['$i', 10]}}")))
).forEach(printBlock);

 

NOTE

Currently, there are no helpers for aggregation expressions. Use the Document.parse() helper to quickly build aggregation expressions from extended JSON.

//For $group operations use the Accumulators helper for any accumulator operations. Below we sum up all the values of i by using the Aggregates.group helper in conjunction with the Accumulators.sum helper:
myDoc = collection.aggregate(singletonList(group(null, sum("total", "$i")))).first();
System.out.println(myDoc.toJson() + "\r\n");

 

Updating documents

To update at most a single document (may be 0 if none match the filter), use the updateOne method to specify the filter and the update document. Here we use the Updates.set helper to update the first document that meets the filter i equals 10 and set the value of i to 110:

//Updating documents
//To update at most a single document (may be 0 if none match the filter), use the updateOne method to specify the filter and the update document. Here we use the Updates.set helper to update the first document that meets the filter i equals 10 and set the value of i to 110:
collection.updateOne(eq("i", 10), set("i", 110));

To update all documents matching the filter use the updateMany method. Here we use the Updates.inchelper to increment the value of i by 100 where i is less than 100.

//To update all documents matching the filter use the updateMany method. Here we use the Updates.inc helper to increment the value of i by 10 where i is less than 10.
UpdateResult updateResult = collection.updateMany(lt("i", 10), inc("i", 10));
System.out.println(updateResult.getModifiedCount() + "\r\n");

The update methods return an UpdateResult which provides information about the operation including the number of documents modified by the update.

Deleting documents

To delete at most a single document (may be 0 if none match the filter) use the deleteOne method:

//Deleting documents
//To delete at most a single document (may be 0 if none match the filter) use the deleteOne method:
collection.deleteOne(eq("i", 11));

To delete all documents matching the filter use the deleteMany method.
Here we delete all documents where i is greater or equal to 100:

//To delete all documents matching the filter use the deleteMany method.
//Here we delete all documents where i is greater or equal to 100:
DeleteResult deleteResult = collection.deleteMany(gte("i", 100));
System.out.println(deleteResult.getDeletedCount() + "\r\n");

The delete methods return a DeleteResult which provides information about the operation including the number of documents deleted.

Bulk operations

These new commands allow for the execution of bulk insert/update/delete operations. There are two types of bulk operations:

  1. Ordered bulk operations.Executes all the operation in order and error out on the first write error.
  2. Unordered bulk operations.Executes all the operations and reports any the errors.Unordered bulk operations do not guarantee order of execution.
MongoCollection<Document> bulkCollection = database.getCollection("bulkCollection");
//Bulk operations
List<WriteModel<Document>> writes = new ArrayList<WriteModel<Document>>();
writes.add(new InsertOneModel<Document>(new Document("_id", 4)));
writes.add(new InsertOneModel<Document>(new Document("_id", 5)));
writes.add(new InsertOneModel<Document>(new Document("_id", 6)));
writes.add(new UpdateOneModel<Document>(new Document("_id", 1), new Document("$set", new Document("x", 2))));
writes.add(new DeleteOneModel<Document>(new Document("_id", 2)));
writes.add(new ReplaceOneModel<Document>(new Document("_id", 3), new Document("_id", 3).append("x", 4)));

// 1. Ordered bulk operation - order is guarenteed
bulkCollection.drop();
bulkCollection.bulkWrite(writes);
bulkCollection.find().forEach(printBlock);
System.out.println("\r\n");

// 2. Unordered bulk operation - no guarantee of order of operation
bulkCollection.drop();
bulkCollection.bulkWrite(writes, new BulkWriteOptions().ordered(false));
bulkCollection.find().forEach(printBlock);

 

References

Download Attachments