ruby on rails -利用Elasticsearch/Tire扁平化多态AR关系



我正在使用一个Rails 3应用程序,允许人们申请赠款等。我们正在使用Elasticsearch/Tire作为搜索引擎。

文件,如拨款提案,由许多不同类型的答案组成,如联系信息或论文。在AR中(通常是关系数据库),您不能直接指定多态的"has_many"关系,因此:
class Document < ActiveRecord::Base
  has_many :answerings
end
class Answering < ActiveRecord::Base
  belongs_to :document
  belongs_to :question
  belongs_to :payload, :polymorphic => true
end

"有效载荷"是针对个别答案类型的模型:联系、叙述、选择题等等。(这些模型的命名空间在"Answerable"下)

class Answerable::Narrative < ActiveRecord::Base
  has_one :answering, :as => :payload
  validates_presence_of :narrative_content
end
class Answerable::Contact < ActiveRecord::Base
  has_one :answering, :as => :payload
  validates_presence_of :fname, :lname, :city, :state, :zip...
end
从概念上讲,答案由答案(类似于连接表的功能,存储所有答案的通用元数据)和可回答对象(存储答案的实际内容)组成。这对于写入数据非常有用。搜索和检索,没有那么多。

我想使用Tire/ES来公开一个更合理的数据表示,以便搜索和读取。在一个正常的Tire设置中,我最终会使用(a)答案索引和(b)叙述、联系人、多项选择等的单独索引。相反,我只想存储文档和答案,可能作为父/子。Answers索引将合并来自Answerings (id, question_id, updated_at…)和Answerables (fname, lname, email…)的数据。这样,我就可以从单个索引中搜索答案,并按类型、question_id、document_id等进行筛选。更新将由应答触发,但每个应答随后将从其应答对象中提取信息。我正在使用RABL来模板我的搜索引擎输入,所以这很容易。

Answering.find(123).to_indexed_json  # let's say it's a narrative
=> { id: 123, question_id: 10, :document_id: 24, updated_at: ..., updated_by: root@me.com, narrative_content: "Back in the day, when I was a teenager, before I had...", answerable_type: "narrative" }

我有几个问题。

  1. 目标是为所有答案提供单一查询解决方案,而不管底层(可回答的)类型如何。我以前从没做过这种事。这看起来像是解决问题的合理方法吗?你能预见我不能预见的皱纹吗?选择/建议/等。欢迎。
  2. 在我看来,棘手的部分是映射。我的计划是为需要索引选项的字段在answer模型中放置显式映射,而只让默认映射处理其余部分:

    mapping do
      indexes :question_id, :index => :not_analyzed
      indexes :document_id, :index => :not_analyzed
      indexes :narrative_content, :analyzer => :snowball
      indexes :junk_collection_total, :index => :not_analyzed
      indexes :some_other_crazy_field, :index
      [...]
    

    如果我不指定某个字段的映射(比如,"fname"),Tire/ES会退回到动态映射吗?

提前感谢。

索引是正确的方法。除了索引字段名,还可以索引方法的结果。

mapping do
  indexes  :payload_details, :as => 'payload_details', :analyzer => 'snowball',:boost => 0
end
def payload_details
  "#{payload.fname} #{payload.lname}" #etc.
end

被索引的值变成了一个duck类型,因此如果对视图中引用的所有值进行索引,那么数据将是可用的。如果您访问未在索引项的模型上索引的属性,它将从ActiveRecord中抓取实例,如果您访问相关模型的属性,我很确定您会得到引用错误,但动态查找器可能会接管。

最新更新