rrbillah
rrbillah

Reputation: 21

Architecture/design suggestion on Cloudant geospatial usage

Cloudant seems to check off nearly all of what we're looking for for our app, but from playing around with it for a bit, I did have a design roadblock.

Our app has a need to pull up the X nearest users nearby. I noticed that there is geo querying available both directly and on top of general search in Cloudant. However, we want to protect our users' location and as such would like a way to query distance from a point, but have results returned with no geo data attached.

I was looking for a way to incorporate a "reduce" on top of the geoindex to filter out sensitive data but that does not seem to exist.

I also know that we could make a server that handles the queries and strips out geo data before returning to the client, but one of the greatest draws of Cloudant was it's Offline First syncing directly from the app side to the DB.

Some location based tutorials involved using Envoy to segment user data (https://developer.ibm.com/clouddataservices/2016/06/14/location-tracker-part-1-offline-first/). That seems to be the direction we want to go, but it's still not exactly it, since users still aren't exposed to each other at all whereas we want everything except for geo data to be available across users.

Do you have a suggestion on how to approach this with Cloudant?

Upvotes: 2

Views: 69

Answers (1)

Raj
Raj

Reputation: 544

To do this, don't use Cloudant Geo for geospatial query, use Cloudant Search, which also has some geospatial querying capabilities. You can't query by polygon, but you can combine non-spatial search with geo. It will let you query on attributes of your data, and sort the results by distance from a point. When you define the index, DO index the geospatial fields, but DO NOT return them to the client (by specifying "store":"false" in the index). I have a blog post on this here: https://developer.ibm.com/clouddataservices/2016/01/07/geospatial-query-with-cloudant-search/

And here's some code using a database at https://opendata.cloudant.com/crimetest.

  1. Look at some of the documents in crimetest: https://opendata.cloudant.com/crimetest/_all_docs?limit=3&include_docs=true

  2. Define a Cloudant Search index: in Cloudant dashboard, add a new Search Index with this:

function (doc) {
  if (doc.properties.source && doc.properties.timestamp && doc.geometry.coordinates) {
    index("description", doc.properties.desc, {"store":true});
    index("timestamp", doc.properties.timestamp, {"store":true});
    index("lat", doc.geometry.coordinates[1], {"store":false});
    index("lon", doc.geometry.coordinates[0], {"store":false});
  }
}

  1. Query it like this: https://opendata.cloudant.com/crimetest/_design/geosearch/_search/spatial?q=*:*&sort=%22%3Cdistance,lon,lat,-90.127519,29.953602,mi%3E%22

You'll get all docs (q=*:*) sorted based on their distance from -90.127519,29.953602. In the response there will be an order field where the first element is the distance from the point, measured in miles (the mi in the query, which can be km instead)

Upvotes: 8

Related Questions