Thinking Sphinx - Показ нужной записи из ассоциации

Я успешно заставил Thinking Sphinx работать с геолокацией на связанной модели. Счастливые дни!

Но теперь мне нужно, чтобы он отображал правильную связанную запись на карте Google.

Сценарий представляет собой компанию с офисами has_many. Офисы имеют значения lng, lat. Я ищу компанию и связываю с ней офисы.

E.g.

  define_index do

 indexes :name, :sortable => true
 indexes offices(:city), :as => :city
 indexes offices(:postal_code), :as => :postal_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

Поиск компании x в месте y / почтовом индексе работает отлично, показывая правильные компании, у которых есть офисы в нужном месте в радиусе @geodist.

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}

Полученные записи представляют собой объект компании, а не офисы, что хорошо для представления списка, но я хочу показать значки на карте Google соответствующего связанного офиса.

Каков наилучший способ найти соответствующую связанную офисную запись для отображения в пределах радиуса?


person Edward Ford    schedule 29.05.2011    source источник


Ответы (1)


Sphinx надежно обрабатывает только атрибуты с плавающей запятой с одним значением и не имеет концепции парных значений широты и долготы. Это означает, что у вас не может быть надежного поиска по объектам с более чем одной парой широта/долгота.

Лучший обходной путь — вместо этого выполнить поиск в Office и, возможно, получить информацию о компании каждого офиса:

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

И затем при поиске вы можете сгруппировать по company_id, чтобы обеспечить только один результат для любой компании (если вы предпочитаете это):

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

Если важно, какой Office будет возвращен для данного company_id, то вы, вероятно, также захотите использовать параметр :group_clause. Документы описывают это.

person pat    schedule 30.05.2011
comment
Спасибо, Пэт, мне тоже нужно присоединиться к услугам компании, но я попытаюсь отменить присоединение с помощью :through.... - person Edward Ford; 30.05.2011