Paul
Developer"Local Results for Local People" - spatial searching in Drupal with SOLR
"I can only go to the edge of town on my bus pass".
Being able to find local services on the web is important to a lot of people, especially to people of an older generation, for reasons ranging from cost of travel, mobility restrictions, to anxiety. A Drupal 7 project we're currently working on has a requirement for curated, directed links to different helpful pages on the web. Most of these are links to local centres and hubs for a variety of services. The requirement is to be able to restrict what links a user can see by distance.
We're leveraging SOLR for our search functionality on this project, which provides a number of useful geolocation and spatial search tools. There is a wealth of information in their official documentation. We use the geofilt parameter, specifying a distance to limit searching. We're doing this inside a custom module which intercepts and modifies the existing search query.
This setup for the query needs to run alongside other search results that are not geolocated. So in order to have this setup, we have to add the geolocation params to the main query, while the filter query (fq) contains all other search parameters that we need.
In order to make our Drupal content play nicely with SOLR's indexing, we use three contrib modules.
LOCATION - This module allows us to specify a field on our content type to be a geospatial field. In our case, we ask users for their postcode upon registration. The module also contains functionality for converting postcodes or other address data into latitude/longitude pairs which is how the core of the geospatial search works.
LOCATION FEEDS – The location feeds module allows us to have our geospatial field auto-mapped when using Feed Imports for adding new content.
APACHE SOLR LOCATION – This module allows us to tell the SOLR index which fields should be indexed as geospatial.
There are some configuration tips that I wish someone had shared with me before setting this up. I will pay this forward to you, reader!
First of all, specify Google as the geotranslation service for a specific country (in our case, the UK) on the Location setup page. Clicking the "Geocoding Options" tab and then "Configure" will allow you to add your API key for the Google Geocoding API. Add your details here.
A second challenge you may come across is working out the correct name for the field to use as the sfield parameter in the SOLR search string. On the Configuration page, click "Apache Solr Search" and the "View more details on the search index contents" which will show you a table of fields. Your geolocation field will have an Index Type of location. Use the field name as your sfield parameter.
Third, you will need to have a starting point for the search. We chose to set a postcode field on the user, which was geolocated using the same Google API. This lat/long pair is the pt parameter of the query.
Finally, our specific case required us to include items without geolocation data because they were not location-sensitive. To do this, we added the string equivalent for our geolocation field and allowed any value, including nulls.
Our eventual location-aware query looked something like this:
$params = array(
'q' => '(-sm_locs_postal_code:[* TO *]) OR ({!geofilt d=10})',
'fq' => $fq_params, /* other search filter stuff */
'fl' => array('*'),
'sfield' => 'locs_field_resource_postcode',
'pt' => $user_location['lat'] . "," . $user_location['lon'],
'rows' => 18
);
If you're attempting something similar, don't forget to reindex!
This solution allows us to have our location-restricted search results which are paginated and sortable as normal. Now our users know that they'll be able to get to help and advice on their current bus pass.