Writing spatial views

Writing spatial views

Spatial views use a single spatial function that is similar to the map function used in MapReduce views. The major difference between MapReduce views and spatial views is that spatial views do not have a map and a reduce function, but only a single function called the spatial function.

You can use the emit() function to create a spatial view. The emit() functions takes the parameters key and value as inputs where the key must be a multidimensional bounding box.

The key can be defined in several ways:
  • Single values

    When the key is specified as a single value, it expands to a collapsed range. For example, the key [1, 2] is stored as [[1, 1], [2, 2]].

  • Ranges

    Use ranges for keys to specify a range of values. For example, you can specify the opening hours of a shop (10:00 to 20:00) as emit([[1000, 2000]], null);

  • GeoJSON geometry
    You can use a GeoJSON geometry in a key. However, it must be the first element of the array. The bounding box is automatically calculated and used as the range. Couchbase Server supports the following GeoJSON objects:
    • Point
    • MultiPoint
    • LineString
    • MultiLineString
    • Polygon
    • MultiPolygon
    • GeometryCollection
    The following is a sample emit() function which uses a GeoJSON geometry in a key:
         emit([{
         "type": "Point",
         "coordinates":[10.9, 48.4]
         }], null);
    Internally, the key is stored as [[10.9, 10.9], [48.4, 48.4]].
    You can combine GeoJSON geometry in the key with single values or ranges. For example, the emit() function to store the categories in a shop and also specify that category 5 refers to clothes can be as shown here:
         emit([{
          "type": "Point",
          "coordinates":[10.9, 48.4]
          }, [1000, 2000], 5], null);
    Note: For backward compatibility, you can also emit a GeoJSON geometry that is not wrapped in an array.
The value parameter for the emit() function can be any arbitrary valid JSON. Here is an example sample view function that emits a point with its height:

    function(doc, meta) {
    if (doc.loc && doc.height && doc.name) {
    emit([doc.loc.lon, doc.loc.lat, doc.height], doc.name);
    }
    }
You can put a spatial view function into a design document by using the object name spatial to indicate the nature of the view definition. For example, the following design document includes the previous function as a view named points.
{
    "spatial" : {
    "points" : "function(doc, meta) {if (doc.loc  && doc.height && doc.name) {
    emit([doc.loc.lon, doc.loc.lat, doc.height], doc.name);}}"
    }
    }
If your document already contains GeoJSON encoded data, you can directly emit that geometry as follows:
function(doc, meta) {
   if (doc.geometry & doc.name) {
   emit([doc.geometry], doc.name);
   }
   }

To execute the spatial query, use the design document format that uses the embedded spatial function. For example, a design document named main that resides within the bucket places is executed with this URL: http://[localhost]:8092/places/_design/main/_spatial/points.