ThinkingSphinx - 通过 has_many 协会搜索

ThinkingSphinx - Search through has_many association

我有两个模型 IdeaIteration 之间的关系。每个想法都可以有很多次迭代。模型看起来像这样;

# idea.rb
has_many :iterations, dependent: :destroy

# I also use with: :real_time 
after_save ThinkingSphinx::RealTime.callback_for(:idea)

# iteration.rb
belongs_to :idea
after_save ThinkingSphinx::RealTime.callback_for(:idea, [:idea])

我的 Idea 索引如下所示:

ThinkingSphinx::Index.define :idea, :with => :real_time do
  [...]
  indexes iterations.title, as: :iteration_titles
  indexes iterations.description, as: :iteration_descriptions
  has iterations.id, :as => :iteration_ids, type: :integer
  [...]
end

我这样搜索:

@ideas = @user.ideas.search  ThinkingSphinx::Query.escape(params[:search]),
  :with => {:team_id => @teams.collect(&:id)},
  :page     => params[:page],
  :per_page => 10,
  :order    => 'created_at DESC'

目前,搜索 Iteration 标题或描述 returns 0 命中。我已经执行了:

rake ts:rebuild
rake ts:regenerate
rake ts:index

我是不是漏掉了什么?

实时索引和 SQL 支持的索引之间的一个区别是,对于 SQL 支持的索引,您在索引定义中引用关联和列,但使用实时索引时间指标,你参考方法。

虽然 iterationsidea 中的实例方法,但 titledescriptionid 不是对象上的方法 return编辑者 iterations.

解决这个问题的最简单方法有两个部分。首先,在Idea中添加实例方法,return迭代相关字段和属性需要的数据:

def iteration_titles
  iterations.collect(&:title).join(' ')
end

def iteration_descriptions
  iterations.collect(&:description).join(' ')
end

def iteration_ids
  iterations.collect &:id
end

然后在您的索引定义中使用这些方法:

indexes iteration_titles, iteration_descriptions
has iteration_ids, :type => :integer, :multi => true

然后,运行 rake ts:regenerate 完成所有设置(ts:rebuildts:index 对实时指数没有意义)。