Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Elasticsearch :through association mapping

I'm trying to index a model when I have a has_many, :through association, but no results are being displayed.

class Business < ActiveRecord::Base
  include Tire::Model::Search
  include Tire::Model::Callbacks

  def self.search(params)
    tire.search(load: true) do
      query { string params[:q]} if params[:q].present?
    end
  end

  mapping do
    indexes :service_name
    indexes :service_description
    indexes :latitude
    indexes :longitude
    indexes :services do
      indexes :service
      indexes :description
    end
  end

  def to_indexed_json #returns json data that should index (the model that should be searched)
    to_json(methods: [:service_name, :service_description], include: { services: [:service, :description]})
  end

  def service_name
    services.map(&:service)
  end

  def service_description
    services.map(&:description)
  end

  has_many :professionals
  has_many :services, :through => :professionals

end

Then this is Service model

class Service < ActiveRecord::Base
  attr_accessible :service, :user_id, :description
  belongs_to :professional
  belongs_to :servicable, polymorphic: true
end

I've also reindex using this:

rake environment tire:import CLASS=Business FORCE=true

I can search for the items in Business, but when I tried to search something in Service, I get an empty result.

like image 497
hellomello Avatar asked Feb 15 '23 19:02

hellomello


2 Answers

After struggling with mapping, I created a gem to make search a bit easier. https://github.com/ankane/searchkick

You can use the search_data method to accomplish this:

class Business < ActiveRecord::Base
  searchkick

  def search_data
    {
      service_name: services.map(&:name),
      service_description: services.map(&:description)
    }
  end
end
like image 150
Andrew Kane Avatar answered Feb 17 '23 22:02

Andrew Kane


I do not believe there is a way to do mapping on associations with Tire. What you will want to do instead is define easily searchable fields with the :as method and a proc. This way you can also get rid of the to_indexed_json method (you will actually need to)

mapping do
  indexes :service_name
  indexes :service_description
  indexes :latitude
  indexes :longitude    
  indexes :service_name, type: 'string', :as => proc{service_name}
  indexes :service_description, type: 'string', :as => proc{service_description}
end
like image 32
Houen Avatar answered Feb 17 '23 20:02

Houen