Location and proximity search on Drupal with Search API Solr

Tech Notes

So this has been on my @TODO list for a long time and I had thought it might be quite difficult. Our patterns include Views, Panels and Search API SOLR so it was that route that we followed. This mean Search API Location was our prefered route. Note that this doesn't imply the Location module but it does use the Geofield module which works nicely with the Address Field module. It was reasonably straight forward to implement however not super well documented so here goes.

The aim is to create a "store finder" essentially. Our application is actually finding a practitioner of a particular form of alternative medicine. That added Profile2 into the mix as the locations were Drupal users.

Prerequisites. A Solr server. See here for Solr 4.x on Linux installation instructions. Or you could use a hosted Solr solution some of which are listed on the Search API Solr page.

  1. Install some modules
    $ drush install ctools views profile2 addressfield geofield search_api search_api_solr search_api_location && drush en -y profile2 addressfield geofield search_api_solr search_api_location search_api_views
  2. Add a Profile with an Address field
    http://example.com/admin/structure/profiles/add
  3. Add a Geofield that geocodes the Address field. Set this to use the Google Geocode type as this is the only type that search_api_location supports currently.
    [[{"fid":"524","view_mode":"default","type":"media","attributes":{"height":89,"width":300,"class":"media-element file-default"}}]]
  4. Add a Solr server. Ours is on port 8983. And the Solr path is /solr/[corename]
  5. Add a Solr index
    http://example.com/admin/config/search/search_api/add_index
  6. Name it Profile index and set the Item type to Profile (note: you can't index Profiles with Nodes as they are different Entity types. However these instructions also apply to Nodes).
  7. Under Fields add a Related field (at the bottom of the page) on the Geocoded Address field and check the indexed column under  LatLong pair
    http://example.com/admin/config/search/search_api/index/profile_index/fields
    [[{"fid":"525","view_mode":"default","type":"media","attributes":{"height":47,"width":300,"class":"media-element file-default"}}]]
  8. Add some User profiles with addresses. When you save them the Address geofield will be geocoded by Google into latitudes and longitudes.
  9. Run the index so that Solr has some content.
    http://example.com/admin/config/search/search_api/index/profile_index
  10. Create a new View
    http://example.com/admin/structure/views/add
  11. Under Show: select Profile index. Continue and edit.
  12. Add some fields. Be sure to include the indexed LatLong pair field.
  13. In the settings for the LatLong pair field check the box Show distance instead of coordinates.
    [[{"fid":"526","view_mode":"default","type":"media","attributes":{"height":231,"width":300,"class":"media-element file-default"}}]]
  14. Add a filter on the Address geocode LatLong pair field. Expose the filter and the operator. This allows the user to change the origin of the search and configure the radius.
  15. Add a sort on the Address geocode LatLong pair field too with Sort ascending. This will sort the results nearest to furthest.

Now the visitor can type in to the expose LatLong search box a natural language string like 2022 NSW or Bondi Junction and find practitioners ordered by distance near Bondi Junction. All the conversion to latitude and longitude courtesy of Google (see their terms of service) and all the hard maths courtesy of Solr.