Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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"
}
like image 246
rash Avatar asked Sep 27 '22 04:09

rash


2 Answers

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.

like image 84
David Ostrovsky Avatar answered Oct 12 '22 23:10

David Ostrovsky


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.

like image 43
kruthar Avatar answered Oct 13 '22 00:10

kruthar