开发者

Thinking Sphinx - Showing the right record from the association

I have successfully got Thinking Sphinx working with Geolocation on an associated model. Happy days!

But I now need it to show the right associated record on a Google map.

The scenario is a Company with has_many offices. Offices have got the lng,lat values. I am searching on the Company and associating the offices to it.

E.g.

  define_index do

 indexes :name, :sortable => true
 indexes offices(:city), :as => :city
 indexes offices(:postal_code), :as => :pos开发者_StackOverflowtal_code

 has "RADIANS(offices.lat)", :as => :lat,  :type => :float
 has "RADIANS(offices.lng)", :as => :lng,  :type => :float

 has created_at
 has updated_at

 set_property :latitude_attr  => 'lat'
 set_property :longitude_attr => 'lng'
 set_property :field_weights  => { 'name'        => 10,
                                  'service_name' => 9,
                                  'city'    => 8 }

 end

Searching for x company in y location / postcode works perfectly, showing the correct companies that have got offices in the desired location within the @geodist radius.

E.g.

{:geo=>[0.9283660690549609, -0.050527407508941975], :sort_mode=>:expr, :sort_by=>"@weight * @weight / @geodist", :with=>{"@geodist"=>0.0..120700.8}, :conditions=>{:service_name=>"Business strategies"}, :page=>1, :per_page=>12, :star=>true}

The resulting records are company object, not the offices, which is fine for the list view but I want to show icons on a google map of the relevant associated office.

What is the best way to find the relevant associated office record to show within the radius bounds?


Sphinx only reliably handles single-value float attributes - and it has no concept of paired lat/lng values. This means that you can't have a solid search across objects with more than one lat/lng pair.

The best workaround is to actually search on Office instead - and perhaps pull in each office's company information:

define_index do
  indexes company.name, :as => :name, :sortable => true
  indexes city, postal_code

  has "RADIANS(offices.lat)", :as => :lat,  :type => :float
  has "RADIANS(offices.lng)", :as => :lng,  :type => :float
  has company.created_at, :as => :created_at
  has company.updated_at, :as => :updated_at
  has company_id

  set_property :field_weights  => {
    'name'         => 10,
    'service_name' => 9,
    'city'         => 8
  }
end

And then when searching, you can group by company_id to ensure only one result for any company (if that's what you'd prefer):

Office.search 'foo',
  :geo            => [lat, lng],
  :with           => {'@geodist' => 0.0..120700.8}
  :group_function => :attr
  :group_by       => 'company_id'

If it's important as to which Office gets returned for a given company_id, then you'll probably want to use the :group_clause option as well. The docs cover this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜