Writing geospatial views
Geospatial support was introduced as an experimental feature in Couchbase Server. This feature is currently unsupported and is provided only for the purposes of demonstration and testing.
GeoCouch adds two-dimensional spatial index support to Couchbase. Spatial support enables you to record geometry data into the bucket and then perform queries which return information based on whether the recorded geometries existing within a given two-dimensional range such as a bounding box. This can be used in spatial queries and in particular geolocationary queries where you want to find entries based on your location or region.
The GeoCouch support is provided through updated index support and modifications to the view engine to provide advanced geospatial queries.
Adding geometry data
GeoCouch supports the storage of any geometry information using the GeoJSON specification. The format of the storage of the point data is arbitrary with the geometry type being supported during the view index generation.
For example, you can use two-dimensional geometries for storing simple location data. You can add these to your Couchbase documents using any field name. The convention is to use a single field with two-element array with the point location, but you can also use two separate fields or compound structures as it is the view that compiles the information into the geospatial index.
For example, to populate a bucket with city location information, the document sent to the bucket could be formatted like that below:
{
"loc" : [-122.270833, 37.804444],
"title" : "Oakland"
}
Views and queries
The GeoCouch extension uses the standard Couchbase indexing system to build a two-dimensional index from the point data within the bucket. The format of the index information is based on the GeoJSON specification.
To create a geospatial index, use the emit() function to output a GeoJSON Point value containing the coordinates of the point you are describing. For example, the following function will create a geospatial index on the earlier spatial record example.
function(doc, meta)
{
if (doc.loc)
{
emit(
{
type: "Point",
coordinates: doc.loc,
},
[meta.id, doc.loc]);
}
}
The key in the spatial view index can be any valid GeoJSON geometry value, including points, multipoints, linestrings, polygons and geometry collections.
The view map() function should be placed into a design document using the spatial prefix to indicate the nature of the view definition. For example, the following design document includes the above function as the view points
{
"spatial" : {
"points" : "function(doc, meta) { if (doc.loc) { emit({ type: \"Point\", coordinates: doc.loc}, [meta.id, doc.loc]);}}",
}
}
To execute the geospatial query you use the design document format using the embedded spatial indexing. For example, if the design document is called main within the bucket places, the URL will be http://localhost:8092/places/_design/main/_spatial/points.
Spatial queries include support for a number of additional arguments to the view request. The full list is provided in the following summary table.
Get Spatial Name | Description |
---|---|
Method | GET /bucket/_design/design-doc/_spatial/spatial-name |
Request Data | None |
Response Data | JSON of the documents returned by the view |
Authentication Required | no |
Query Arguments | |
bbox | Specify the bounding box for a spatial query |
Parameters : string; optional | |
limit | Limit the number of the returned documents to the specified number |
Parameters : numeric; optional | |
skip | Skip this number of records before starting to return the results |
Parameters : numeric; optional | |
stale | Allow the results from a stale view to be used |
Parameters : string; optional | |
Supported Values | |
false : Force update of the view index before results are returned | |
ok : Allow stale views | |
update_after : Allow stale view, update view after access |
Bounding Box Queries If you do not supply a bounding box, the full dataset is returned. When querying a spatial index you can use the bounding box to specify the boundaries of the query lookup on a given value. The specification should be in the form of a comma-separated list of the coordinates to use during the query.
These coordinates are specified using the GeoJSON format, so the first two numbers are the lower left coordinates, and the last two numbers are the upper right coordinates.
For example, using the above design document:
GET http://localhost:8092/places/_design/main/_spatial/points?bbox=-180,-90,0,0
Content-Type: application/json
Returns the following information:
{
"total_rows": 0,
"rows": [
{
"id": "oakland",
"key": [
[
-122.270833,
-122.270833
],
[
37.804444,
37.804444
]
],
"value": [
"oakland",
[
-122.270833,
37.804444
]
],
"geometry": {
"coordinates": [
-122.270833,
37.804444
],
"type": "Point"
}
}
]
}