I have a use case to query data by geo location and string value at the same time:
select poi.* where location nearby [point, distance] and poi.category = ‘Restaurant’
Note: I have created a spatial view, but the view map function only accepts multi-dim number value.
N1QL itself does not exploit the spatial view for geo predicates.
Spatial view does not allow me to put any string value. This means, I have no way to query (either N1QL or view) geo location and other string values in one shot, right?
That’s correct. We don’t have an integrated solution now.
For now, you can create a GSI index containing lat / lon / and some distances that you are interested in.
I can imagine how to query POI in a box (by restrict the lon/lat value in a range). Any idea for a radius/circle query in N1QL?
I don’t remember the details from high school trigonometry. Something about square root of sum of squares.
N1QL provides a SQRT function which you can use in your query (and your GSI index).
You can also use the box in your index, which will filter things considerably, and then apply the SQRT on top that in your query.
Appreciate for the reply.
Thanks to Google. I found the formula. It’s a little bit complex but doable. Considering return to high school for trigonometry
Thanks a lot,
Strongly recommend to add GeoSpatial Function to N1QL. None of the Spatial query condition looks simple. I have handle cross180degree case plus some long trigonometry formula.
Sounds good. If you have a list of common functions you would like to see, we can take that into account. Thanks for the suggestion.
This query does the job of both filtering on strings and distance. Formulae from http://stackoverflow.com/questions/13026675/calculating-distance-between-two-points-latitude-longitude.
select name, geo, city, (ACOS(SIN(PI()* geo.lat/180.0)*SIN(PI()*37.7/180.0)+COS(PI()*geo.lat/180.0)*
COS(PI()*37.7/180.0)*COS(PI()*-122.33/180.0-PI()*geo.lon/180.0))*6371) as distance
from `beer-sample` b
WHERE type = 'brewery' AND
COS(PI()*37.7/180.0)*COS(PI()*-122.33/180.0-PI()*geo.lon/180.0))*6371) < 10
and state = 'California'
order by distance asc;
You can try this on beer-sample yourself. While this exploits the index on type and state, it still can’t use any index for the spatial index.
Spatial indices use bounding boxes to find the nearest qualifying locations.
This case is a post scan filter…
Thank you. I have a written a similar one. Anyway, do you have a query to find a POI located in a box (top-left and bottom-right)?
Hi @zhaoshenhao, Please take a look at this: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates.
It has examples for both calculating the distance and creating the b-tree indices on lat-long.
I haven’t tried this yet.
Hi, What is the last solution of this topic, does Couchbase upgraded to support location queries?