Search code examples
ruby-on-railssolrsunspot

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

Solution

  • 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