Currently, the search by location is executed by retrieving the list of postal codes that fall within a certain proximity of the submitted search point. The list of postal codes is then used to query the {location} table. This is undesirable for a few reasons:
(1) The query for the list of postal codes is done against a table where there are 37,000+ postal codes. The query involves doing comparisons on the latitude, longitude columns to get the "square" region of valid postal codes. An extra condition in the WHERE clause that involves some trig functions is used to narrow the "square" to the perfect "circle". In short, this query can be expensive on such a large table. The idea is that, since we already save lat/lon from the postal code table into the (node|user) table, and since there are much less users|nodes than postal codes, why not run this query on those tables instead?
(2) Another reason is that the list can get really huge, depending on the search proximity. A 250-mile search radius on a Brooklyn postal code will yield a list that is more than 1000 postalcodes long. And each one of the postal codes comes with extra baggage (like city, province, and distance from the search point). Of course, not every postal code is going to have a search result, so why chew up memory with such a long list when we can just get the results we want by querying directly on the latitude/longitude in the {user} and {node} tables.
(3) Finally, this method of executing proximity searches will only turn up nodes that have a postal code, and only then if that country has a free postal code database that is being used. With the addition of the optionally toggle-able lat/lon input interface, it will be possible (once this task is completed) to search for things by location even if those things don't have a postal code.
In the end, the current search algorithm might work out for situations where there are 20,000+ geotagged nodes (that is my rough estimate pulled out of thin air... not totally).
So, in short. I'd like to rewrite the query to query against the lat/lons in the user and node tables directly, rather than querying against the lat/lons in the zipcodes table and then using the list of results from that table to query against the user and node tables.
-Ankur
Comments
Comment #1
boris mann commented+1...especially for a non-US centric view of the world. I would probably move stuff that relies heavily on zipcodes to another module.
Comment #2
jamesJonas commentedWould use of the MySQL spatial extensions help solve some of the issues concerning efficient search of spatial data? This opens the doors to a much larger suite of spatial types and searching strategies.
GIS and Spatial Extensions with MySQL
http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html
Chapter 16. Spatial Extensions
http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html
These have had some time to cook since introduction in 4.1 (currrent version of Mysql is 5.0.19)
PostgreSQL has some capabilities via an add-on, PostGIS. PostGIS is a geographic information system software program that adds support for geographic objects to the PostgreSQL object-relational database.
Just a thought.
- james
Comment #3
bdragon commentedMarking as duplicate of #319278: [master][meta] Location_search rewrite.
(Eventually geo.module will handle the spatial searching.)