user3099794
user3099794

Reputation: 66

Cloudsearch geo query filter/limit by distance

I am using cloud search with lambda, I face a problem with geo query (i m using haversin ).

I need to get nearby data (marketers) based on user's current longitude/latitude, compared with marketer longitude /latitude stored in db.

I am able to get all the data sorted by distance, but not able to limit/filter by distance, kindly suggest how to achieve this with cloudsearch.

var params = {
    query: "matchall",
    expr:"{\"distance\":\"haversin(13.185474,77.524030,latlon.latitude,latlon.longitude)\"},{\"expr.distance\":{,5}}",        
    queryParser:"structured",
    sort:"distance asc",
    return:"id,distance,latlon,_score"};  

In the above query I am getting distance in return and also data sorted by distance, now want to limit it for only 5 or 10 kms.

Please suggest any alternate way if it is not possible with cloudsearch (any other way then haversin). I need to get nearby data with limited kms.

Upvotes: 1

Views: 787

Answers (1)

Peter Fennema
Peter Fennema

Reputation: 1690

With CloudSearch you can apply a filter query to get all data within a bounding box (docs). CloudSearch does not have the option to get locations within a circle. But when you have all data within a bounding box of (for example) 5 km, sorted by distance, it is easy to remove the data > 5km from the CloudSearch result set with a Lambda function. So, the solution for you is to add a filter query to your params, and do a simple post processing on the result of the CloudSearch query.

Now suppose you want all data within distance dist from point lat,lng

First calculate the bounding box coordinates. I use the geopoint library for this calculation.

  var GEO = require('geopoint');
  var point = new GEO(lat, lng);
  var points = point.boundingCoordinates(Number(dist), -1, true); //[(SW), (NE)]
  var SW = points[0];
  var NE = points[1];

  // GeoPoint expresses the boundingbox via SW, NE. CloudSearch uses NW, SE
  var NWlat = NE.latitude();
  var NWlng = SW.longitude();
  var SElat = SW.latitude();
  var SElng = NE.longitude();

Next step is to add a filterquery to your params:

var params = {
    ...
    “filterQuery” = latlon:['" + NWlat + "," + NWlng + "','" + SElat + "," + SElng + "'],
    ...
}

Now the CloudSearch query will give you all points within a bounding box, ordered by distance. The only thing left to do is to remove the "data > distance" from the result set

Upvotes: 1

Related Questions