Abram
Abram

Reputation: 41874

Multi-value spatial search with Sunspot Solr

At the moment I am indexing my providers using Sunspot Solr based on their latitude and longitude.

class Provider < ActiveRecord::Base
  searchable do
    text :full_name, :as => :full_name_textp
    latlon(:location) { Sunspot::Util::Coordinates.new(latitude, longitude) }
  end
end

As it turns out some of my providers work at multiple locations (branches). There is a guide for multi-value spatial searching with Solr here. Here is the official reference.

Based on the guide, it seems I need to add the following to my schema.xml

<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
           distErrPct="0.025"
           maxDistErr="0.000009"
           units="degrees" />

and..

<dynamicField name="locm_*" type="location_rpt" indexed="true"  stored="true" multiValued="true"/>

Now I'm just guessing but would my searchable block be something along the lines of:

class Provider < ActiveRecord::Base
  searchable do
    text :full_name, :as => :full_name_textp
    latlon(:locm_location) do 
      branches.each do
        Sunspot::Util::Coordinates.new(latitude, longitude)
      end
    end
  end
end

When I try to run Provider.reindex I receive the error message:

ArgumentError: locm_location is not a multiple-value field, so it cannot index values []

ANSWER:

Thanks to @zrl3dx I have a working solution now. Here is the modified code:

latlon(:location_locm, :multiple => true) do 
  branches.each do
    Sunspot::Util::Coordinates.new(latitude, longitude)
  end
end

For those wishing to implement this, I had this in my searchable block:

with(:location_locm).in_radius(x, y, 15, :bbox => true)

Also, I needed to add this to my branch.rb

  def lat
    self.latitude
  end

  def lng
    self.longitude
  end

Upvotes: 4

Views: 1007

Answers (2)

Abram
Abram

Reputation: 41874

Thanks to @zrl3dx I have a working solution now.

Here is the modified code:

latlon(:location_locm, :multiple => true) do 
  branches.each do
    Sunspot::Util::Coordinates.new(latitude, longitude)
  end
end

For those wishing to implement this, I had this in my searchable block:

with(:location_locm).in_radius(x, y, 15, :bbox => true)

Also, I needed to add this to my branch.rb

  def lat
    self.latitude
  end

  def lng
    self.longitude
  end

Upvotes: 2

zrl3dx
zrl3dx

Reputation: 7869

Just for clarification, except obvious answer for that question (adding :multiple => true to searchable block - you can't use such fields for sorting!), one has to realize that solr != sunspot:

  • solr is a search engine (which uses Apache's Lucene)
  • sunspot is a very nicely written DSL (especially when compared to those huge xml config files - java heritage) on top of solr which exposes large portion of solr options (or even all, I'm not sure)

So basically, if you want to adapt some answer for solr you should try to 'wind' it in sunspot's DSL.

Upvotes: 3

Related Questions