Java SDK

Fork me on GitHub Welcome to the Java SDK 2.0, the next generation of database access. It provides functionality to store and retrieve your documents to and from a Couchbase Server cluster through synchronous and asynchronous (reactive) interfaces - and it even has support for Java 8.

Storing Documents

Creating or replacing a Document is easy. JSON is a first-class citizen, but we also provide support for anything else (for example serialized Java Objects). This is how you can create a JSON document and insert it synchronously:

JsonObject user = JsonObject.empty()
  .put("firstname", "Walter")
  .put("lastname", "White")
  .put("job", "chemistry teacher")
  .put("age", 50);
JsonDocument stored = bucket.upsert(JsonDocument.create("walter", user));

Retrieving Documents

You can also retrieve your stored documents in a variety of ways. This first example synchronously loads a Document identified by its ID and prints out a field of the JSON. Notice how the JSON handling is done for you:

JsonDocument walter = bucket.get("walter");
System.out.println("Found: " + walter.getString("firstname"));

That doesn't impress you? Asynchronous, reactive APIs are also exposed. The following example utilizes Java 8 as well to showcase a more advanced query:

bucket
  .async()
  .get("beer")
  .onErrorResumeNext(bucket.async().getFromReplica("beer", ReplicaMode.ALL))
  .first()
  .map(doc -> doc.content().getString("name"))
  .timeout(2, TimeUnit.SECONDS)
  .doOnError(System.err::println)
  .onErrorReturn(error -> "Not Found!");

This code snipped loads a document, falls back to a replica read if an error happens, grabs the first of potentially many replica responses and then extracts the beer name. Finally a timeout is applied and more error handling (printing out the errors) is added as well. This gives you a glimpse of what's possible with our asynchronous, reactive methods which are always available. In fact, the synchronous calls are just convenience wrappers.

Querying

Couchbase Server has extensive support for querying (be it through Views or the experimental N1QL query language). The SDK naturally provides ways to query them. Here is how to query a view which gives us beers and breweries, filters out the beers and prints their name:

ViewResult result = bucket.query(ViewQuery.from("beers_and_breweries", "by_name"));

Iterator<ViewRow> rowIterator = result.rows();
while (rowIterator.hasNext()) {
    ViewRow row = rowIterator.next();
    JsonDocument doc = row.document();

    if (doc.content().getString("type").equals("beer")) {
        System.out.println(doc.content().getString("name"));
    }
}

This can also be done asynchronously:

bucket
    .async()
    .query(ViewQuery.from("beers_and_breweries", "by_name"))
    .flatMap(AsyncViewResult::rows)
    .flatMap(AsyncViewRow::document)
    .filter(doc -> doc.content().getString("type").equals("beer"))
    .subscribe(doc -> System.out.println(doc.content().getString("name")));

Finally, here is how to run a N1QL query - notice how nicely the DSL leads you to your final query:

bucket
  .query(select("*").from("beer-sample").limit(10))
  .doOnNext(result -> {
      if (!result.success()) {
          System.err.println(result.error());
      }
  })
  .flatMap(QueryResult::rows)
  .toBlocking()
  .forEach(row -> System.out.println(row.value()));
  

This query selects all documents from the beer-sample bucket and prints each rows content. Of course, synchronous execution is also available!