ruby-on-rails - 使用 Elasticsearch/Tire 展平多态 AR 关系

标签 ruby-on-rails elasticsearch tire

我正在使用 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

“有效负载”是个别答案类型的模型:联系人、叙述、多项选择等。 (这些模型在“可回答”下命名空间。)

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 等进行过滤。更新将从 Answering 触发,但每个回答都会从其 answerable 中提取信息。我正在使用 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. 在我看来,棘手的部分是映射。我的计划是将显式映射放入需要索引选项的字段的应答模型中,让默认映射处理其余部分:

    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

索引值变为鸭子类型,因此如果您索引在 View 中引用的所有值,数据将可用。如果您访问未在索引项的模型上建立索引的属性,它将从 ActiveRecord 中获取实例,如果您访问相关模型的属性,我很确定您会遇到引用错误,但动态查找器可能接管。

关于ruby-on-rails - 使用 Elasticsearch/Tire 展平多态 AR 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14323805/

相关文章:

ruby-on-rails - 设计错误消息!为 nil :NilClass 导致未定义的方法 `errors'

ruby-on-rails - 格式化 Rails 控制台输出

elasticsearch - 在代码中生成查询主体

ruby-on-rails - Config Tire与Bonsai ElasticSearch Heroku附加组件一起使用

ruby-on-rails - 是否可以让 Capistrano 通过反向 SSH 隧道进行结帐?

ruby-on-rails - Rails 显示具有特定字段值的数据

elasticsearch - 在嵌套属性中使用 function_score 增强 Elasticsearch

elasticsearch - 如何在 Elasticsearch 中首先获得最受欢迎的结果

ruby - 如果与特定ID匹配,则提升Tire中查询的结果?

sorting - 轮胎/Elasticsearch:排序无效