I wrote a custom module to perform a search of an index I created using Search API and Search API Solr Search. The search is a proximity search that finds the closest locations using a bounding box, but I can't figure out how to SORT the results I get back by the closest. Here is my module code in entirety:
<?php
function s_test() {
$index = search_api_index_load("articles");
$query = new SearchApiQuery($index);
$lat = 41.920110;
$lon = -87.680433;
//get min/max lat and long
$check_radius = 25; // radius of bounding circle in miles
$earth_radius = 3960; // earth's mean radius, miles
// first-cut bounding box (in degrees)
$max_lat = $lat + rad2deg($check_radius/$earth_radius);
$min_lat = $lat - rad2deg($check_radius/$earth_radius);
// compensate for degrees longitude getting smaller with increasing latitude
$max_lon = $lon + rad2deg($check_radius/$earth_radius/cos(deg2rad($lat)));
$min_lon = $lon - rad2deg($check_radius/$earth_radius/cos(deg2rad($lat)));
// set the bounding box
$filter = $query->createFilter('AND');
$filter->condition('latitude', $max_lat, '<=');
$filter->condition('latitude', $min_lat, '>=');
$filter->condition('longitude', $max_lon, '<=');
$filter->condition('longitude', $min_lon, '>=');
$query->filter($filter);
// run query
$data = $query->execute();
$results = $data['results'];
print_r($results);
}
function s_index() {
$index = search_api_index_load("articles");
$index->reindex();
search_api_index_items($index);
print '<pre>';
print_r($index);
print '</pre>';
}
function test_query_menu() {
//create the search page
$items['test-search'] = array(
'title' => t('Search'),
'page callback' => 's_test',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM
);
//create a re-index page
$items['test-index'] = array(
'title' => t('Index'),
'page callback' => 's_index',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM
);
return $items;
}
/**
* Implements hook_entity_property_info_alter().
*/
function test_query_entity_property_info_alter(&$info) {
$info['node']['properties']['latitude'] = array(
'type' => 'decimal',
'label' => t('Latitude'),
'sanitized' => TRUE,
'getter callback' => 'test_query_search_api_property_latitude_getter_callback',
);
$info['node']['properties']['longitude'] = array(
'type' => 'decimal',
'label' => t('Longitude'),
'sanitized' => TRUE,
'getter callback' => 'test_query_search_api_property_longitude_getter_callback',
);
$info['node']['properties']['latlongpair'] = array(
'type' => 'string',
'label' => t('LatLong Pair'),
'sanitized' => TRUE,
'getter callback' => 'test_query_search_api_property_latlongpair_getter_callback',
);
$info['node']['properties']['logo_uri'] = array(
'type' => 'string',
'label' => t('LOGO URI'),
'sanitized' => TRUE,
'getter callback' => 'test_query_search_api_property_logo_uri_getter_callback',
);
}
/**
* Getter callback for latitude.
*/
function test_query_search_api_property_latitude_getter_callback($item) {
return $item->field_address[LANGUAGE_NONE][0]['latitude'];
}
/**
* Getter callback for longitude.
*/
function test_query_search_api_property_longitude_getter_callback($item) {
return $item->field_address[LANGUAGE_NONE][0]['longitude'];
}
/**
* Getter callback for latitude/longitude pair.
*/
function test_query_search_api_property_latlongpair_getter_callback($item) {
return $item->field_address[LANGUAGE_NONE][0]['latitude'] . ',' . $item->field_address[LANGUAGE_NONE][0]['longitude'];
}
/**
* Getter callback for logo uri.
*/
function test_query_search_api_property_logo_uri_getter_callback($item) {
return $item->field_image[LANGUAGE_NONE][0]['uri'];
}
Basically I exposed my latitude and longitude to Solr and used those to set the bounding box and this works find to return results close to me, but I don't see any field in the results set that would allow me to sort by the node with the closest location.
I also tried installing the Search API Location module, but I still can't find anything in the results set to sort by.
I'm using Location and Location CCK module to get the lat/long.
If anyone has experience/insight with this that would be groovy.