So far Drupal 6 & Apachesolr 6.2.beta5 & SOLR 3.4 are returning results based on relevancy and plotting the current paginated group on a views 3 gmap with location module doing the proximity. It shows the proximity but a subsequent paginated result-item may be closer - and it is slow as location module is doing the math. So the problem is I need an option to sort by distance proximity for the whole result set not just the current paginated group.

I have been trying to get the Content profile -> Location cck (field_location) Indexed into SOLR so I can use lat/long to use solr geoproximity function. But I cant get the lat/long indexed into SOLR

Ive been following these two tutorials. Using either method the lat long is not correctly indexed into SOLR
http://drupal.org/node/1187888#comment-4767290 (D7 but this one comment is for D6)
http://ericlondon.com/geospatial-apache-solr-searching-drupal-6-upgradin...

Does anyone have the problem. If you have D6 and SOLR Proximity working working please share your steps & process. Changes to schema.xml / changes to hook_modify_query() / changes to apachesolr.module or apachesolr_search.module
Please and thanks in advance for any assistance. SOLR is the bees knees!! I am keen to test and document any efforts, ideas or processes.

Comments

jimijamesi’s picture

So with more trial and error I have this working:
Key difference was I had to use apachesolr-6.x-2.x-dev (oct29/2011) which is newer than beta5 (may 31/2011)
Here is the process I followed:

Schema.xml changes

     <fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
     <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
     <fieldtype name="geohash" class="solr.GeoHashField"/>
     <field name="coordinates" type="location" indexed="true" stored="true"/>
     <dynamicField name="*_coordinate"  type="tdouble" indexed="true"  stored="false"/>

MYMODULE hooks

function MYMODULE_apachesolr_update_index(&$document, $node) {
  // check for node location
  //if (!empty($node->location['latitude'])&&!empty($node->location['longitude'])) {
  //  $document->coordinates = $node->location['latitude'] . ',' . $node->location['longitude'];
  //}

  // check for cck field location
  if (!empty($node->field_location[0]['latitude'])&&!empty($node->field_location[0]['longitude'])) {
    $document->coordinates = $node->field_location[0]['latitude'] . ',' . $node->field_location[0]['longitude'];
  }
}

function MYMODULE_apachesolr_modify_query(&$query, &$params, $caller) {
  if ($caller == 'apachesolr_search') {
    $params['fq'] = '{!geofilt}'; // filter query
    $params['sfield'] = 'coordinates'; // document field
    $params['pt'] = '21.346617,-82.098747'; // latitude,longitude
    $params['d'] = 5; // distance
    $params['sort'] = 'geodist() asc'; // sort by distance
  }
}

Changed against 6.x-2.x-dev

apachesolr.module - line 1693

--  if ($keys == '' && isset($params['fq'])) {
++  if ($keys == '' && isset($params['fq']) && (is_array($params['fq']) || is_object($params['fq']))) {

apachesolr_search.module - line 261

--  if (isset($params['fq'])) {
++  if (isset($params['fq']) && (is_array($params['fq']) || is_object($params['fq']))) {

thanks to vishun for these adjustments (above)

At this point I was getting fatal error when doing a search:
Fatal error: Cannot use string offset as an array in /Applications/MAMP/htdocs/ontfresh/sites/all/modules/apachesolr/apachesolr.module on line 1552
So then I added a line to apachesolr.module
$params['fq'] = array_merge($fq, $params['fq']);
existing code... apachesolr.module (line 1552)

  // Add array of fq parameters.
  if ($query && ($fq = $query->get_fq())) {
    foreach ($fq as $delta => $values) {
      if (is_array($values) || is_object($values)) {
        foreach ($values as $value) {
          $params['fq'][$delta][] = $value;
        }
      }
    }
  }

modified code

  // Add array of fq parameters.
  if ($query && ($fq = $query->get_fq())) {
    $params['fq'] = array_merge($fq, $params['fq']);
    foreach ($fq as $delta => $values) {
      if (is_array($values) || is_object($values)) {
        foreach ($values as $value) {
          $params['fq'][$delta][] = $value;
        }
      }
    }
  }

At this point I am getting the results sorted by proximity via solr and getting location and non-location results displaying as expected. So thanks to http://ericlondon.com for this part:
$params['fq'] = array_merge($fq, $params['fq']);

If anyone has some opinions or tweaks please chime in.
Thanks to all the maintainers too for all your awesome work on SOLR

nick_vh’s picture

Have you seen that in the Drupal 7 version a schema for solr 3.4 was added? Maybe you can use this one also? OR at least get the dynamic fields for solr 3.4 from there.

I'd like to continue this one and maybe get something in a patch but the 6.2 version is a bit abandoned (at least as far as support goes)
Soon a lot of features from Drupal 7 will flow back in the Drupal 6 release so this will be much easier to do I guess.

Thanks for the effort so far, I'm sure it might be useful for someone

jimijamesi’s picture

Ok thanks I will check out the 3.4 schema.xml changes in 7.x

I noticed that while the Solr is returning results ordered from a dynamic centre point (default, user pin location, smart_ip, postal code->lat/long) the proximity distance or radius is not working at all even when hardcoded into the hook_apachesolr_modify_query(). However when I use the proximity distance in solr/admin it does reduce results to within that distance.

Perhaps the 3.4 schema.xml changes will help with this. I will continue to document findings in this post. thx.

LGLC’s picture

Thank you so much for your posts, jimijamesi! You and the blog you linked to pointed me in the right direction and I've finally got the distance filter working!

I've got this working on apachesolr-6.x-2.x-beta5 by doing the following:

1) Downloading version 3.4.0 of solr from http://apache.mirror.anlx.net/lucene/solr/

2) Copying over the appropriate files, as mentioned in the first part of http://ericlondon.com/geospatial-apache-solr-searching-drupal-6-upgradin...

3) Making the schema.xml additions mentioned in the above blog (and by you):

<fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
<fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
<fieldtype name="geohash" class="solr.GeoHashField"/>

<field name="coordinates" type="location" indexed="true" stored="true"/>
<dynamicField name="*_coordinate"  type="tdouble" indexed="true"  stored="false"/>

4) Adding in the module hook to update the index with the coordinates from the appropriate fields (as mentioned by you and the above blog). My fields were not called the same as yours, so I (obviously!) had to adjust the filed names to suit my needs:

function MYMODULE_apachesolr_update_index(&$document, $node) {
 // check for location data
  	if (!empty($node->field_job_advert_location_form[0]['latitude']) && !empty($node->field_job_advert_location_form[0]['longitude'])) {
    	$document->coordinates = $node->field_job_advert_location_form[0]['latitude'] . ',' . $node->field_job_advert_location_form[0]['longitude'];
  	}  
}

3) (THIS IS WHERE WE DIFFER) I then simply added a filter to the query in hook_apachesolr_modify_query, as noted in http://drupal.org/node/1197212#comment-4750032 and in the handbook at http://drupal.org/node/443986:

function MYMODULE_apachesolr_modify_query(&$query, &$params, $caller) {

  // NOTE: hardcoded area coordinates:  
  $coordinates = '42.346617,-71.098747';  
  // Distance (in km)
  $distance = 10;
  
  // Add in distance filter
  $query->add_filter('_query_', '"{!geofilt sfield=coordinates pt='.$coordinates.' d='.$distance.'}"');
}

I didn't implement any sorting at all, but will give that a go next. Also, I'm planning to use some of the Location module's geocoding (or the Google Maps API) to take a string input, with a country dropdown, and turn it into some coordinates - and to allow users to enter a distance. That should get around the need to hard-code it in.

Thanks again - I wouldn't have been able to get this working without you! I hope others are able to get this working, too, so that we can continue to improve Solr's location searches.

nick_vh’s picture

Status: Active » Closed (duplicate)

#1187888: Geospatial searching with solr 3.x duplicate of the geo issue for Drupal 7 branch of apachesolr. Closing this one and referencing this in the other issue