arjunmehta / node-georedis

Super fast geo queries.
MIT License
192 stars 33 forks source link

[Enhancement] Paging for geo.nearby #16

Open nicolas-raoul opened 8 years ago

nicolas-raoul commented 8 years ago

My app shows a list of nearby ATMs. At first only the 20 closest ATMs are shown in the list (see screenshot below). When the user scrolls, more ATMs are loaded from node-georedis. As the user scrolls more and more, they get further and further ATMs.

An ideal geographic database would return ATMs in concentric rings, allowing an offset parameter in the request, and keeping a kind of cache internally so that subsequent requests do not cost more and more CPU/memory.

If would be great if node-georedis could provide this paging. Meanwhile, if you have any tricks for dealing with this kind of situation I would be glad to hear about them :-) Cheers!

screenshot from 2016-08-31 12-06-52

arjunmehta commented 8 years ago

@nicolas-raoul Unfortunately there is no way to do paging as you describe in a very performant way, even when using the native interface. :(

You will have to do some form of sorting by distance within a given radius, and then cache it for further paging.

Because this module uses redis, we're limited by the algorithm Redis uses which is centered around geohashes. We're also limited because Redis does not do combinations of queries (ie. we can't subtract one query from the other, like in SQL).

In dealing with this situation:

Cache sorted results for each query in a Redis Zset

This is the only way I can think of making it work for you. You'd have to do the implementation, but here are some ideas: You could cache sorted results in a dedicated Redis sorted set (zset) for each query. Zsets let you page quite easily. If a user does a query near their location, perform the query, sort it in node, and cache the results using a sorted set. Then if another user close to that user makes a similar query, check if a cached result exists, then use that as a way to page results. You will only see performance gains if you have many users in the same area doing the same query. You will also use more memory by caching the results.

Other DB solutions

There are other DB solutions (ArcGIS, postGIS etc) which may solve your problem (while introducing more)

Use a UI pattern that groups by distance range

A common UI pattern you can use (which I've seen well used) is grouping results by distance.

Results sorted by distance: Within 1km Within 10km Within 100km

I don't want to speak to the users of your app, but usually the nearest are the most relevant anyway.

You'll still need to filter out previous smaller areas for each larger query. But I guess what I'm saying here is to manage user expectations, sometimes design solves the problem :D

Hope this helps!

m9rco commented 6 years ago

For this, I was thinking about how to implement paging, I think is the final use PGSQL to complete detailed paging