rash
rash

Reputation: 91

Search for documents within a given radius with Couchbase

I want to write a geospatial view that takes searches for the following document within a one mile radius from a given latitude and longitude. How do I do this?

{
   "agree_allowed":true,
   "assigned_by":"",
   "assigned_to":"",
   "comments_allowed":true,
   "location": {
    "coordinates": [
      "-74.168868",
      "40.854655"
    ],
    "type": "Point"
  },
   "subscribed":{
      "user_cfd29b81f0263a380507":true,
      "user_cfd29b81f0263a3805010":true
   },
   "type":"report",
   "user_id":"user_cfd29b81f0263a380507",
   "username":"test17"
}

Upvotes: 5

Views: 449

Answers (3)

Patryk Celiński
Patryk Celiński

Reputation: 57

With spatial views, you can search only by bounding box.

You may want to search within radius - is hidden in Full-Text Search ... https://docs.couchbase.com/server/current/fts/fts-geospatial-queries.html

Upvotes: 0

David Ostrovsky
David Ostrovsky

Reputation: 2481

Because you can only use bounding-box queries with Couchbase spatial views, you will have to split your distance query into two steps:

  1. Query Couchbase for coordinates that fall within a bounding box that matches your radius.
  2. Filter out coordinates returned by #1 that are further than the radius you specified.

For the first step, you'll need to write a spatial view as follows:

function(doc, meta)
{
  if (doc.location)
     emit(doc.location, [meta.id, doc.location]);
}

Note: this is the Couchbase 3.0 version of the view, in Couchbase 4 you don't need to emit the meta.id and doc.location in the value anymore.

Now, given a starting point (lat,lon) and radius r, you need to calculate a bounding box [lat1,lon1, lat2,lon2] to query the view for a list of documents whose coordinates potentially fall within the radius you want. The bounding box query in Couchbase specifies the bottom-left and top-right coordinates.

Next, in your application, iterate over all the results and check whether they really do fall within R distance of your starting point.

Depending on how much accuracy you need, you can either assume the Earth is flat and just do the calculations on a 2D plane, which will be inaccurate but not terribly so for a distance of 1 mile. Or alternatively, use the actually accurate formulae to calculate everything, as described in this excellent article: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates

Or better yet, you can use a geolocation library for the language of your choice to calculate the bounding box and the distances. Here's one for C# and one for Java.

Upvotes: 3

kruthar
kruthar

Reputation: 309

Check out the GeoSpatial views documentation in Couchbase: http://docs.couchbase.com/4.0/views/spatial-views.html

One approach you could take is to index all of your documents with a 1 mile bounding box around their location.

Then you would query that view with the start_range and end_range being the same range, which would be just the location of the of your document above. This would return to you all the documents where the point falls within its 1 mile bounding box.

You can use GeoJSON for more precise bounding boxes, unfortunately they don't have a circle in the Specs, so depending on how advanced you made your bounding box, you could get results that are not exactly within a mile from your query location.

Upvotes: 1

Related Questions