Quick Tour (original) (raw)
- Getting Started
- Quick Tour
The following code snippets come from the QuickTour.java
example code that can be found with the driver source.
Note
See the installation guidefor instructions on how to install the MongoDB Reactive Streams Java Driver.
important
This guide uses the Subscriber
implementations as covered in the Quick Tour Primer.
Make a Connection
The following example shows multiple ways to connect to the database mydb
on the local machine, using theMongoClients.create helper.
// To directly connect to the default server localhost on port 27017
MongoClient mongoClient = MongoClients.create();
// Use a Connection String
MongoClient mongoClient = MongoClients.create("mongodb://localhost");
// or a Connection String
MongoClient mongoClient = MongoClients.create(new ConnectionString("mongodb://localhost"));
// or provide custom MongoClientSettings
ClusterSettings clusterSettings = ClusterSettings.builder().hosts(asList(new ServerAddress("localhost"))).build();
MongoClientSettings settings = MongoClientSettings.builder().clusterSettings(clusterSettings).build();
MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase("mydb");
At this point, the database
object will be a connection to a MongoDB server for the specified database.
Note
The API only returns Publisher<T>
when network IO required for the operation. ForgetDatabase("mydb")
there is no network IO required. A MongoDatabase
instance provides methods to interact with a database but the database might not actually exist and will only be created on the insertion of data via some means; e.g. the creation of a collection or the insertion of documents.
MongoClient
The MongoClient
instance actually represents a pool of connections for a given MongoDB server deployment; you will only need one instance of classMongoClient
even with multiple concurrently executing asynchronous operations.
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(String collectionName)method:
The following example gets the collection test
:
MongoCollection<Document> collection = database.getCollection("test");
Insert a Document
Once you have the collection object, you can insert documents into the collection. For example, consider the following JSON document; the document contains a field info
which is an embedded document:
{
"name" : "MongoDB",
"type" : "database",
"count" : 1,
"info" : {
x : 203,
y : 102
}
}
To create the document using the Java driver, use theDocument class. You can use this class to create the embedded document as well.
Document doc = new Document("name", "MongoDB")
.append("type", "database")
.append("count", 1)
.append("info", new Document("x", 203).append("y", 102));
To insert the document into the collection, use the insertOne()
method.
collection.insertOne(doc).subscribe(new OperationSubscriber<Success>());
important
In the API all methods returning a Publisher
are “cold” streams meaning that nothing happens until they are Subscribed to.
The example below does nothing:
Publisher<Success> publisher = collection.insertOne(doc);
Only when a Publisher
is subscribed to and data requested will the operation happen:
publisher.subscribe(new Subscriber<Success>() {
@Override
public void onSubscribe(final Subscription s) {
s.request(1); // <--- Data requested and the insertion will now occur
}
@Override
public void onNext(final Success success) {
System.out.println("Inserted");
}
@Override
public void onError(final Throwable t) {
System.out.println("Failed");
}
@Override
public void onComplete() {
System.out.println("Completed");
}
});
Once the document has been inserted the onNext
method will be called and it will print “Inserted!” followed by the onComplete
method which will print “Completed”.
If there was an error for any reason the onError
method would print “Failed”.
Add Multiple Documents
To add multiple documents, you can use the insertMany()
method.
The following example will add multiple documents of the form:
{ "i" : value }
Create the documents in a loop.
List<Document> documents = new ArrayList<Document>();
for (int i = 0; i < 100; i++) {
documents.add(new Document("i", i));
}
To insert these documents to the collection, pass the list of documents to theinsertMany()
method.
subscriber = new ObservableSubscriber<Success>();
collection.insertMany(documents).subscribe(subscriber);
subscriber.await();
Here we block on the Publisher
to finish so that when we call the next operation we know the data has been inserted into the database!
Count Documents in A Collection
Now that we’ve inserted 101 documents (the 100 we did in the loop, plus the first one), we can check to see if we have them all using thecount()method. The following code should print 101
.
collection.count()
.subscribe(new PrintSubscriber<Long>("total # of documents after inserting "
+ " 100 small ones (should be 101): %s"));
Query the Collection
Use the find()method to query the collection.
Find the First Document in a Collection
call the first() method on the result of the find() of method
To get the first document in the collection, call thefirst()method on the find()operation. collection.find().first()
returns the first document or if no document is found the publisher just completes. This is useful for queries that should only match a single document, or if you are interested in the first document only.
subscriber = new PrintDocumentSubscriber();
collection.find().first().subscribe(subscriber);
subscriber.await();
The example will print the following document:
{ "_id" : { "$oid" : "551582c558c7b4fbacf16735" },
"name" : "MongoDB", "type" : "database", "count" : 1,
"info" : { "x" : 203, "y" : 102 } }
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.
Find All Documents in a Collection
To retrieve all the documents in the collection, we will use thefind()
method. The find()
method returns a FindPublisher
instance that provides a fluent interface for chaining or controlling find operations. The following code retrieves all documents in the collection and prints them out (101 documents):
subscriber = new PrintDocumentSubscriber();
collection.find().subscribe(subscriber);
subscriber.await();
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. For example, if we wanted to find the document for which the value of the “i” field is 71, we would do the following:
import static com.mongodb.client.model.Filters.*;
collection.find(eq("i", 71)).first().subscribe(new PrintDocumentSubscriber());
will eventually print just one document:
{ "_id" : { "$oid" : "5515836e58c7b4fbc756320b" }, "i" : 71 }
Get a Set of Documents with a Query
We can use the query to get a set of documents from our collection. For example, if we wanted to get all documents where "i" > 50
, we could write:
// now use a range query to get a larger subset
collection.find(gt("i", 50)).subscribe(new PrintDocumentSubscriber());
which should print the documents where i > 50
.
We could also get a range, say 50 < i <= 100
:
collection.find(and(gt("i", 50), lte("i", 100))).subscribe(new PrintDocumentSubscriber());
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 FindPublisher
. Below we use the [exists()]({{ < coreapiref "com/mongodb/client/model/Filters.html#exists-java.lang.String-">}}) helper and sort[descending("i")]({{ < coreapiref "com/mongodb/client/model/Sorts.html#exists-java.lang.String-">}}) helper to sort our documents:
collection.find(exists("i")).sort(descending("i")).subscribe(new PrintDocumentSubscriber());
Projecting fields
Sometimes we don’t need all the data contained in a document. The Projectionshelpers can be used to build the projection parameter for the find operation and limit the fields returned.
Below we’ll sort the collection, exclude the _id
field and output the first matching document:
collection.find().projection(excludeId()).subscribe(new PrintDocumentSubscriber());
Updating documents
There are numerous update operatorssupported by MongoDB.
To update at most a single document (may be 0 if none match the filter), use the updateOnemethod to specify the filter and the update document. Here we update the first document that meets the filter i
equals 10
and set the value of i
to 110
:
collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 110)))
.subscribe(new PrintSubscriber<UpdateResult>("Update Result: %s"));
To update all documents matching the filter use the updateManymethod. Here we increment the value of i
by 100
where i
is less than 100
.
collection.updateMany(lt("i", 100), new Document("$inc", new Document("i", 100)))
.subscribe(new PrintSubscriber<UpdateResult>("Update Result: %s"));
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 deleteOnemethod:
collection.deleteOne(eq("i", 110))
.subscribe(new PrintSubscriber<DeleteResult>("Delete Result: %s"));
To delete all documents matching the filter use the deleteMany method.
Here we delete all documents where i
is greater or equal to 100
:
collection.deleteMany(gte("i", 100)
.subscribe(new PrintSubscriber<DeleteResult>("Delete Result: %s"));
The delete methods return a DeleteResult, which provides information about the operation including the number of documents deleted.
Bulk operations
These commands allow for the execution of bulk insert/update/delete operations. There are two types of bulk operations:
- Ordered bulk operations.
Executes all the operation in order and error out on the first write error. - Unordered bulk operations.
Executes all the operations and reports any the errors.
Unordered bulk operations do not guarantee order of execution.
Let’s look at two simple examples using ordered and unordered operations:
// 1. Ordered bulk operation - order is guaranteed
subscriber = new PrintSubscriber<BulkWriteResult>("Bulk write results: %s");
collection.bulkWrite(
Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
new InsertOneModel<>(new Document("_id", 5)),
new InsertOneModel<>(new Document("_id", 6)),
new UpdateOneModel<>(new Document("_id", 1),
new Document("$set", new Document("x", 2))),
new DeleteOneModel<>(new Document("_id", 2)),
new ReplaceOneModel<>(new Document("_id", 3),
new Document("_id", 3).append("x", 4)))
).subscribe(subscriber);
subscriber.await();
// 2. Unordered bulk operation - no guarantee of order of operation
subscriber = new PrintSubscriber<BulkWriteResult>("Bulk write results: %s");
collection.bulkWrite(
Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
new InsertOneModel<>(new Document("_id", 5)),
new InsertOneModel<>(new Document("_id", 6)),
new UpdateOneModel<>(new Document("_id", 1),
new Document("$set", new Document("x", 2))),
new DeleteOneModel<>(new Document("_id", 2)),
new ReplaceOneModel<>(new Document("_id", 3),
new Document("_id", 3).append("x", 4))),
new BulkWriteOptions().ordered(false)
).subscribe(subscriber);
subscriber.await();
important
Use of the bulkWrite methods is not recommended when connected to pre-2.6 MongoDB servers, as this was the first server version to support bulk write commands for insert, update, and delete in a way that allows the driver to implement the correct semantics for BulkWriteResult and BulkWriteException. The methods will still work for pre-2.6 servers, but performance will suffer, as each write operation has to be executed one at a time.