One of the neat features of Sphinx is the ability to sort and filter by a calculated geographical distance, from latitude and longitude values. It’s quite easy to get set up, as well.
Setting up the Indexes
Firstly, you’ll need to be storing latitude and longitude values as
attributes for each relevant document. So, in your
you’ll need something like this, if you’ve already got the columns in
Keep in mind, though, that Sphinx needs these values to be floats, and tracking positions by radians instead of degrees. If this isn’t the case in your own database (which isn’t a surprise - most people store the values as degrees), then you’ll need to manually convert columns for the attributes:
Once this is done, you’ll need to rebuild your Sphinx indexes:
You can name your attributes to be whatever you like - Thinking Sphinx will automatically use them if they’re called latitude, longitude, lat, lon or lng. If you’re using something a little less standard, then you can set up your index to still use the attributes automatically:
Once your indexes are set up, then you can begin searching. You need to make sure you’re doing two things:
- Provide a geographical reference point
- Filter or sort by the calculated distance
For the first, you can provide an array of two arguments (latitude and
longitude, again in radians) to the
:geo option. For the second,
you’ll need to refer to Sphinx’s internal attribute
@geodist in a
filter and/or a sort argument.
If you do not provide any reference to
@geodist, then the lat/lng
values will be ignored by Sphinx.
Don’t forget: Sphinx expects the latitude and longitude values to be in radians - so you will probably need to convert the values when searching.
There’s two ways to access the calculated distance. You can either
enumerate through the collection using
Or, you can access the distance as part of the
It’s worth noting that the distance is in metres - so those stuck on the Imperial system (Americans, that’s you), you might want to convert to less archaic measurements.