Today we are releasing version 2.2.0 of the Couchbase .NET SDK. The major focus for this release is feature compatibility with Couchbase Server 4.0 GA which was also released today! The core features in this release are:

  • N1QL support
  • Multidimensional Scaling (MDS) support
  • Enhanced durability
  • GEO Spatial Views

Along with those major features, the 2.2.0 SDK also contains several bug fixes and improvements. If you are using an earlier version of the SDK, it's strongly suggested that you upgrade to this latest version.

Full release notes are available here.

N1QL: A new SQLlike query language for JSON

Without a doubt the mos significant feature released with Couchbase Server 4.0 is complete support for querying JSON documents with N1QL, a new SQL like query language for documents. Version 2.2.0 of Couchbase .NET SDK fully supports N1QL through a new client API.

The QueryRequest class

The QueryRequest class represents a N1QL query request to Couchbase Server. It encapsulates the N1QL REST API over port 8093 and provides a type-safe interface for executing queries. Along with the internal query client built into the CouchbaseBucket class, it handles a lot of the plumbing and complexity of the REST API, for example:

  • Retry logic temporary and recoverable failures
  • Uniform distribution of queries throughout the cluster
  • Logic for handling prepared statements
  • Uri caching
  • Mapping query results to POCOs
  • et al

The QueryRequest class separates the actual N1QL statement from the execution, error handling and data mapping of the results of the query. Here is an example of using the QueryRequest to build a request that will later be executed against the CouchbaseBucket:

First we create the QueryRequest object and pass in a N1QL statement into it. Then we add a positional parameter (note names parameters are also supported). Finally we override the global ClientConfiguration.QueryRequestTimeout value with a custom timeout of 500 milliseconds.

Once we have a QueryRequest created we can execute it against a CouchbaseBucket using the Query method:

That's it! The new API has the following methods and properties exposed by QueryRequest:

Method Description Optional
Statement Sets a N1QL statement to be executed. false
Prepared Sets a N1QL statement to be executed in an optimized way using the given queryPlan. true
Timeout Sets the maximum time to spend on the request. true
ReadOnly If a GET request, this will always be true otherwise false. true
Metrics Specifies that metrics should be returned with query results. true
AddNamedParameter Adds a named parameter to the parameters to the statement or prepared statement. true
AddPositionalParameters Adds a positional parameter to the parameters to the statement or prepared statement. true
ScanConsistency Specifies the consistency guarantee/constraint for index scanning. true
AddHoc If set to false, the client will try to perform optimizations transparently based on the server capabilities, like preparing the statement and then executing a query plan instead of the raw query. true

These are the pragmatic and fully supported parameters. In addition there are parameters/methods for Compression, Format and Encoding, but I do not suggest they are used at this time. Also, ScanConsistency of of AtPlus and StatementPlus are not currently supported and will throw a NotSupportedException if passed in.

The QueryResult class

Once a request has been sent to server and processed, a response will be returned back to the client in the form of a JSON document. The client will take the response and map it to the QueryRequest class. The client will also analyze the status codes of the response (both N1QL and HTTP) and determine if the request should be retried or not. In general, any HTTP 400 errors will not be retried they will be returned back to the caller because then indicate a client issue.

The notable properties and methods of the QueryRequest class are as follows:

Method Description
Success True if query was successful.
Message Optional message returned by query engine or client
Exception If Success is false and an exception has been caught internally, this field will contain the exception.
RequestId Gets the request identifier.
ClientContextId Gets the clientContextID of the request, if one was supplied. Used for debugging.
Signature Gets the schema of the results. Present only when the query completes successfully.
Rows Gets a list of all the objects returned by the query. An object can be any JSON value.
Status Gets the status of the request; possible values are: success, running, errors, completed, stopped, timeout, fatal.
Errors Gets a list of 0 or more error objects; if an error occurred during processing of the request, it will be represented by an error object in this list.
Warnings Gets a list of 0 or more warning objects; if a warning occurred during processing of the request, it will be represented by a warning object in this list.
Metrics Gets an object containing metrics about the request.
HttpStatusCode Gets the HTTP status code for the request.

The Success field is generally used to indicate success/failure of a query request and if it has failed, the Errors, Warnings, Status and HttpStatusCode fields can be used to diagnose the error/issue so that it can be resolved.

Using Prepared Statements

Every statement executed by the server must have an associated query plan created which takes time and resources. Prepared statements allow the generated query plan to reused over and over again improving overall performance and server health. To use prepared statements, the AdHoc parameter must be set to false:

The SDK will handle the preparation, caching and reuse of the prepared statement for this statement and all future requests with it.

Multi-dimensional scaling

Also, known as MDS, Multi-dimensional scaling is a new feature of Couchbase Server 4.0 that allows you assign the services you wish to run on a particular node in your cluster. For instance, if you have a four node cluster, one node could be dedicated to queries, one node dedicated to indexing and two nodes dedicated to the data service – or some combination services can run on a particular node. The SDK itself is aware of which nodes support the respective services and will route queries and keys to the correct node in the cluster “automagically”

Enhanced Durability

Enhanced durability is a new way enforcing durability constraints. Durability constraints are constraints that you place on a mutation to ensure that a key has been replicated and/or persisted to “n” replicas. The big difference between the older “observe” based durability constraints is that the enhanced durability uses a replica sequence number to determine if a key has achieved the desired ability, while “observe” compares the replica state of the key itself.

Enhanced durability is not a change to the existing key/value API's, but instead is simply a configuration change; the rest is done “under the hood” by the internal APIs of the SDKs:

The key here is that UseEnhancedDurability was set to true on the BucketConfiguration for the “default” bucket. The external durability API is the same; the PersistTo and ReplicateTo fields are passed in along with the key and value with the desired durability which must be met before the operation will return.

GEO Spatial Views

A new twist to an old Couchbase server is support for GEO Spatial views. GEO spatial views are created by defining Map functions using JavaScript (reduce is not supported) that allow you to query geographic ranges.

Here is an example of a Spatial View:

The SDK API for using Spatial Views is very similar to the View API, but uses a special SpatialViewQuery class to construct an object which is then submitted to the CouchbaseBucket class for execution.

You can learn more about writing Spatial Views here.

How to get it

The SDK is available for download directly, through NuGet, or by cloning and pulling the Github repo:

  • Download the binaries here.
  • The NuGet package can be found here.
  • The Github repo is here.


Posted by Jeff Morris, Senior Software Engineer, Couchbase

Jeff Morris is a Senior Software Engineer at Couchbase. Prior to joining Couchbase, Jeff spent six years at Source Interlink as an Enterprise Web Architect. Jeff is responsible for the development of Couchbase SDKs and how to integrate with N1QL (query language).

Leave a reply