MapReduce Views
Edit this article in GitHub
Version 2.4

MapReduce Views

You can use MapReduce views to create query-able indexes in Couchbase Server.

The normal CRUD methods allow you to look up a document by its ID. A MapReduce (view query) allows you to look up one or more documents based on various criteria. MapReduce views are comprised of a map function that is executed once per document (this is done incrementally, so this is not run each time you query the view) and an optional reduce function that performs aggregation on the results of the map function. The map and reduce functions are stored on the server and written in JavaScript.

MapReduce queries can be further customized during query time to allow only a subset (or range) of the data to be returned.

Tip: See the Incremental MapReduce Views and Querying Data with Views sections of the general documentation to learn more about views and their architecture.

The following example is the definition of a by_name view in a "landmarks" design document in the "travel-sample" sample dataset. This view checks whether a document is a landmark and has a name. If it does, it emits the landmark's name into the index. This view allows landmarks to be queried for by it's "name" field.

function (doc, meta) {
    if (doc.type && doc.type == "landmark" && doc.name) {
        emit(doc.name, null);
    }
}

A Spatial View can instead be queried with a range or bounding box. For example, let's imagine we have stored landmarks with coordinates for their home city (eg. Paris, Vienna, Berlin and New York) under geo, and each city's coordinates is represented as two attributes, lon and lat. The following spatial view map function could be used to find landmarks within Europe, as a "by_location" view in a "spatial" design document:

function (doc, meta) {
    if (doc.type && doc.type == "landmark" && doc.geo) {
        emit([doc.geo.lon, doc.geo.lat], null);
    }
}

Querying Views through the .NET SDK

Once you have a view defined, it can be queried from the .NET SDK by using the Query(IViewQueryable query) method on the CouchbaseBucket class. Here is an example:

Querying simply MapReduce view
var cluster = new Cluster(new ClientConfiguration());
var bucket = cluster.OpenBucket("travel-sample"));

var query = new ViewQuery().From("landmarks", "by_name").Limit(10);
var landmarks = bucket.Query<dynamic>(query);
foreach (var landmark in landmarks.Rows)
{
    Console.WriteLine(landmark.Key);
}
The Query(IViewQueryable query) method takes a ViewQuery, which is the standard implementation of IViewQueryable, executes the query and returns back the result of query as a IViewResult. Some useful methods and properties of the ViewQuery class include (others can be seen in the reference documentation):
  • DesignDoc: sets the name of the design document.
  • View: sets the name of the view to query
  • Asc: return the documents in ascending by key order
  • Desc: return the documents in descending by key order
  • Skip: skip this number of records before starting to return the results
  • Limit: limit the number of the returned documents to the specified number
  • Key: return only documents that match the specified key.
  • Keys: return only documents that match one of keys specified within the given array
The Query(IViewQueryable query) returns an IViewResult implementation that contains the results of the query plus additional information regarding the status of the query, which is useful for debugging:
  • Rows: the results of the query if successful as an IEnumerable<ViewRow>.
  • TotalRows: the total count of all rows.
  • Values: a list containing only the Value property of each ViewRow returned by Rows.
  • Success: true if the request was successful.
  • Exception: if Success is false and an exception has been caught internally, this field will contain the exception.
  • Error: an error message if one occurred.
The ViewRow represents each row returned by the view request and contains properties for the document Id, the Key and the Value if it was emitted. Here is another example of a more advanced query:
Querying a MapReduce view
var cluster = new Cluster(new ClientConfiguration());
var bucket = cluster.OpenBucket("travel-sample"));

var query = new ViewQuery().From("landmarks", "by_name").Limit(10).StartKey("A").EndKey(@"A\u0fff");
var landmarks = bucket.Query<dynamic>(query);
foreach (var landmark in landmarks.Rows)
{
    Console.WriteLine(landmark.Key);
}

Here's some sample output for the previous query:

A R M Chicken
A. Cavalli &

Querying Geospatial Views

To query a geospatial view, you will need to construct a SpatialViewQuery object (Couchbase.Views.SpatialViewQuery). Spatial queries accept a StartRange and an EndRange parameter which allow you to limit the enclosing bounding boxes of the result. The arguments to these parameters are List<double> 's with each element corresponding to a component emitted by the key (the first two components implicitly being the longitude and latitude of the result itself).

On output, spatial queries yield instances of SpatialViewRow classes. A SpatialViewRow is similar to a ViewRow, with an added Geometry property.

Advanced querying a spatial view
var cluster = new Cluster(new ClientConfiguration());
var bucket = cluster.OpenBucket("travel-sample"));

var query = new SpatialViewQuery().From("spatial", "by_location")
                .Bucket("travel-sample")
                .StartRange(new List<double?> { 0, -90})
                .EndRange(new List<double?> { 180, 90 })
                .Limit(10);

var result = bucket.Query<dynamic>(query);
foreach (var viewRow in result.Rows)
{
    Console.WriteLine(viewRow.Value);
}
In the example above, we create a Cluster object and then open a CouchbaseBucket called "travel-sample" from the Cluster object. We then construct a SpatialViewQuery that will target the "by_location" view on the "spatial" design document. We then pass the start and end coordinates in via the StartRange and EndRange methods and finally we limit are results to 10 items with the Limit method. The query is executed by passing it into the CouchbaseBucket.Query<T>(IViewQueryable query) method which returns an IViewResult implementation with the results of the query.