A apachesorl spatial plugin (submodule) that integrates with solr search and the locations module would be awesome.

Indexing locations and searching by distance is something that is so logical.

This might come in handy:
http://derickrethans.nl/spatial-indexes-solr.html

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pwolanin’s picture

Well, yes that would be nice, but need some solid and tested configuration stanzas to support geo fields in the context of the rest of our configuration.

pwolanin’s picture

Title: spatial searching with solr » Geospatial searching with solr 3.2

Any work around this will require use of Solr 3.2+ on the server side.

pwolanin’s picture

Here is a Solr 3.2 war file (rename it from .zip to solr.war) built from the ASF lucene svn 3.2 tag with patches using javac 1.6.0_24. For issues/patches see https://issues.apache.org/jira/browse/SOLR

Note the patch for SOLR-2462 I generated from the commit, since it seems the final patch was never posted to the issue.

Issue Patch file
SOLR-232 https://issues.apache.org/jira/secure/attachment/12477249/SOLR-232.patch
SOLR-2462 http://drupal.org/files/issues/SOLR-2462.patch
SOLR-2535 https://issues.apache.org/jira/secure/attachment/12483071/SOLR-2535.patch
wouters_f’s picture

thanx pwolanin I'll give this a try asap.

wonder95’s picture

I've been planning on adding the geospatial capability to Solr starting in a couple weeks (when I finish a current project), so please keep me in the loop if you start anything.

orbiteleven’s picture

FWIW I was only able to get this running with the following: http://drupal.org/node/1197212

mcabalaji’s picture

Hi

SOLR 3.3 has been released which has the fixes to the bug mentioned in #3 and as well some performance optimization and new features

It also has new features like

"automaton-based, implementation of suggest (autocomplete) component, offering an order of magnitude smaller memory consumption compared to ternary trees and jaspell and very fast lookups at runtime "

The Complete release notes is in the link : http://svn.apache.org/repos/asf/lucene/dev/tags/lucene_solr_3_3/solr/CHA...

So I think we should start integrating SOLR 3.3 with Drupal

pwolanin’s picture

Unfortunately, https://issues.apache.org/jira/browse/SOLR-2535 was not committed for 3.3

pwolanin’s picture

Since Solr 3.3 was released we can skip at least the spellcheck patch. The file handler patch is nice to have, but won't prevent Solr from otherwise working with Drupal.

mcabalaji’s picture

Hi

I tried to implement the GEO spatial with Drupal using the PATCH #3 and with SOLR 3.2 and I was able to see GEO spatial working . Following are the Schema Changes and the Process I followed to make it work

SCHEMA 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"/>

STEP 1:

Next, I added a hook_apachesolr_update_index() function to a custom module to index Location CCK data into the Solr Document.

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

STEP 2 :

I then add a hook_apachesolr_modify_query() function to my custom module to override the Solr query params.

        function MYMODULE_apachesolr_modify_query(&$query, &$params, $caller) {
            if ($caller != 'apachesolr_search') {
               continue;
           }
           // NOTE: Hardcoded the Co-ordinates 
           // You can also get the user co-ordinates and send along with this
           $coordinates = '21.346617,-82.098747';  
           $distance = 5;  
           // modify params
           $params['fq'][] = "{!geofilt sfield=coordinates pt=$coordinates d=$distance}";  
       }

// The spatial query syntax has an augmented "fq" value, but the apachesolr Drupal module sets the fq parameter automatically (via: $query->get_fq()) , So for this I need to make a change to the apachesolr contrib module

     function apachesolr_modify_query(&$query, &$params, $caller) { 
         // TODO: The query object should hold all the params.
        // Add array of fq parameters.
       if ($query && ($fq = $query->get_fq())) {
           $params['fq'] = array_merge($fq, $params['fq']);
      }

IF STEP 2 isn't working For Testing you can change in the apachesolr views query.inc

      /**
       * Executes the query and fills the associated view object with according
       * values.
       * 
       * Values to set: $view->result, $view->total_rows, $view->execute_time,
       * $view->pager['current_page'].
       */
       public function execute(&$view) {
               // NOTE: hardcoding to check whether Distance Works  
	      $coordinates = '21.346617,-82.098747';
	      $distance = 5;
              $this->_params['sfield']='coordinates';
	      $this->_params['pt']= $coordinates;
	      $this->_params['d']= $distance;
	      $geo_params = "{!geofilt}";
	      array_push($this->_params['fq'],$geo_params);
       } 

And then I was able to see the Results show up based on Distance and I was able to do a SORTING based on Distance . The new spatial query syntax (documented here: http://wiki.apache.org/solr/SpatialSearch)

Hope this Helps

Thanks
Balaji

pwolanin’s picture

Right, so we cannot do:

<dynamicField name="*_coordinate"

because our other dynamic fields use prefixes. So we need to flip this around, maybe:

<dynamicField name="coordinate_*"
vishun’s picture

Hey there,

I was indeed able to get this to work. Thank you very much pwolanin and mcabalaji, this is beautiful. I changed some small things that allows apachesolr_modify_query() in apachesolr.module to remain as it was, however, a small unobtrusive change elsewhere in apachesolr.module AND apachesolr_search.module is needed.

MYMODULE.module

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']))) {
pwolanin’s picture

Title: Geospatial searching with solr 3.2 » Geospatial searching with solr 3.3
FileSize
7.11 MB

http://svn.apache.org/repos/asf/lucene/dev/tags/lucene_solr_3_3/solr/CHA...

is out now. Let's target that as our next baseline from 1.4.x

Attached is a 3.3 war (rename as above) which includes patches SOLR-2535 and SOLR-232. The other bug is fixed in 3.3.

wouters_f’s picture

FileSize
49.17 KB

Completely off topic, I love the business here, thanks you guys, this sh!t is great!

Now, as I want to put the workable solution in the issue, is this all correct?

I installed a plain vanilla ubuntu server (selected tomcat in installer)
-I added the zip file (from post #13, thanks pwolanin) to the webapps folder (after renaming it to solr.war)
http://drupal.org/files/issues/apache-solr-3.3-ACQUIA-PATCHED.zip
-I created the solr working foders and config files for a multiple solr cores. (extract attachement into /var/lib/tomcat6/solr)
-I added the following schema changes (from post #10, thanks mcabalaji) (starting from schema name="drupal-1.4" version="1.2">)
changes added from post #11

   <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"/>

All this seems to produce no errors on the solr side, I will test the suggested hooks asap.
**wild thought**, maybe this stuff could be in the apachesolr_geo module?

vishun’s picture

I personally think it would be awesome if Spatial Search became part of apachesolr itself, perhaps as a separate submodule but perhaps otherwise orchestrated via module settings. One thing I did not include in my post was a module that I've yet to release called Locator which will automatically try to determine the user's location and store it to their session. It gracefully degrades through HTML5 GeoLocation, Maxmind's GeoIP, and simple user input.

/me needs to finish and release that module one of these days.

pwolanin’s picture

@drupal_sensei - I'm not sure that schema snippet is correct.

Look in more detail at the Solr 3.3 example.

The _d suffix appears to refer to:

 <dynamicField name="*_d"  type="double" indexed="true"  stored="true"/>
wouters_f’s picture

Oops, it seems I still cant get it right.

again from the start:

1. downloaded apachesolr module, using included schema.xml (drupal-3.0-beta7)
Then altered the schema.xml with following lines:

<del><fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/></del>
<dynamicField name="*_d"  type="double" indexed="true"  stored="true"/>
<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"/>

2. Installed solr with the default solrconfig and altered schema file.

3. succesfully connected the apachesolr server.
Indexed all the content (which has a location cck field).

4. The code suggested in postr #12 should look like this (I Guess) for Drupal 7

function apachesolr_geo_apachesolr_update_index(&$document, $node) {
  if (!empty($node->field_location[0]['latitude'])&&!empty($node->field_location[0]['longitude'])) {
    $document->coordinates = $node->field_location['und'][0]['latitude'] . ',' . $node->field_location['und'][0]['longitude'];
  }
}
function apachesolr_geo_apachesolr_query_alter(&$query) {
   $query->addParam('fq','{!geofilt}' );
   $query->addParam('sfield','coordinates' );
   $query->addParam('pt', '21.346617,-82.098747');
   $query->addParam('d', 5);
   $query->addParam('sort', 'geodist() asc');
}

4. Without the query alter the search works, with the params added it fails.
I see the field types Geohash and location in my solr, but not the fields.
Thats probably why i get the following error while doing the query:

SEVERE: org.apache.solr.common.SolrException: can not use FieldCache on unindexed field: coordinates
	at org.apache.solr.schema.SchemaField.checkFieldCacheSource(SchemaField.java:171)

Feels like I am close to get it to work.

pwolanin’s picture

we should not use a suffixed field like *_d. This will certainly conflict at some point with a prefixed field, though in theory all our existing prefixes are more specific.

Look at the example schema, instead of specifying a suffix, apparently you can specify a field type like:

<fieldType name="point" class="solr.PointType" dimension="2" subFieldType="double"/>
<fieldType name="location" class="solr.LatLonType" subFieldType="tdouble"/>

Though this will create a suffixed synamix field, it will be even more specific.

Also, I got some feedback about this from Yonick on the solr-user list, so you might read that exchange.

wouters_f’s picture

Short summary of the BoF @ drupalcon
Problem :
Different versions of the schema are being used.
Drupal site builders are afraid of/dont understand the schema file.
The apachesolr multilingual module uses a mechanism where it extends a default schema file with field types depending on user languages. The geo functionality has the same need.

What I remembered from the Bof:

  • extra schema fields to be added for multilingual indexing.
    Comments should be added in the schema file so admins can edit it to their wishes.
  • extra schema fields should/could be added for geospatial indexing (built in in solr from).
  • A filter on distance makes sense for spatially indexed results (see geofilt/geodist) http://wiki.apache.org/solr/SpatialSearch
    http://wiki.apache.org/solr/SpatialSearch says that will be built in in Solr 4.0.
pwolanin’s picture

I must not have been at the same BoF - none of those summary points match what I remember discussing or suggesting.

I said we will not build any kind of schema builder, but rather add some markers to the schema to facilitate the multilingual module.

wouters_f’s picture

It appears I misunderstood.
I am sorry for that.
I updated the summary to represent what you said.

jimijamesi’s picture

Title: Geospatial searching with solr 3.4 » Geospatial searching with solr 3.3

Solr 3.4 returns results but wont return a mix of location nodes and non-location nodes

Update: using 6.2.x and the modifications above Solr is now returning location and non-location nodes in its search result.
Still cant get proximity results only results based on relevancy
following #12 gave some errors and field_location latlong is not being indexed.

Update2: I got this working with 6.2.x.dev I documented my effort here
http://drupal.org/node/1334960

pwolanin’s picture

FileSize
27.45 KB

Here's a possible schema.xml that at at least allows me to index lat/lon.

The dynamic field prefixes aren't great, but not sure if I can come up w/ better.

pwolanin’s picture

Status: Active » Needs review
FileSize
143.26 KB
egrotke’s picture

How is this patch applied? Doesn't seem to match up with Drupal instructions for applying a patch.
Any help would be greatly appreciated

Thanks!

egrotke’s picture

Oh okay, found it here: http://drupal.org/node/620014

pwolanin’s picture

Title: Geospatial searching with solr 3.3 » Geospatial searching with solr 3.4

3.4 is out...

pwolanin’s picture

Status: Needs review » Active

Committing this patch as the basis for further refinement.

wouters_f’s picture

ygerasimov has implemented geospatial searching with solr in drupal.
http://drupal.org/project/search_api_location

pwolanin’s picture

Title: Geospatial searching with solr 3.3 » Geospatial searching with solr 3.4

@drupal_sensei - that's for Solr 1.4 using an external geo library, not directly relevant to this issue.

Nick_vh’s picture

Title: Geospatial searching with solr 3.4 » Geospatial searching with solr 3.x

Making this generic for the solr 3.x branch.

Nick_vh’s picture

#1334960: SOLR 3.4 & D6.x indexing location nodes more info can also be found in this (closed) issue

Nick_vh’s picture

Component: Miscellaneous » Contrib
Status: Active » Postponed

Adding this to Contrib Component. Good for someone to pick up to develop a contributed module and marking postponed until someone picks it up

Nick_vh’s picture

Status: Postponed » Closed (won't fix)

Won't fix here. See apachesolr_geo or apachesolr_location for more information on geo searching