5

私は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 を使用して、検索と読み取りのためにデータのより健全な表現を公開したいと考えています。通常のタイヤのセットアップでは、(a) 回答用のインデックスと、(b) 説明、連絡先、複数の選択肢など用の個別のインデックスを作成します。代わりに、おそらく親/子として、ドキュメントと回答を保存したいと思います。Answers インデックスは、Answerings (id、question_id、updated_at...) と Answerables (fname、lname、email...) からのデータをマージします。このようにして、1 つのインデックスから Answers を検索し、type、question_id、document_id などでフィルター処理できます。更新は Answering からトリガーされますが、各 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. 私が見ているように、トリッキーな部分はマッピングです。私の計画は、インデックス作成オプションが必要なフィールドの Answering モデルに明示的なマッピングを配置し、残りはデフォルトのマッピングに任せることです。

    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 は動的マッピングにフォールバックしますか? (使用されるすべてのフィールドを明示的にマップする必要がありますか?)

前もって感謝します。もっと具体的に教えてください。

4

1 に答える 1

0

インデックス作成は、これを行うための正しい方法です。フィールド名にインデックスを付けるとともに、メソッドの結果にインデックスを付けることができます。

mapping do
  indexes  :payload_details, :as => 'payload_details', :analyzer => 'snowball',:boost => 0
end

def payload_details
  "#{payload.fname} #{payload.lname}" #etc.
end

インデックス付きの値はダック型になるため、ビューで参照するすべての値にインデックスを付けると、データが利用可能になります。インデックス化されたアイテムのモデルでインデックス化されていない属性にアクセスすると、ActiveRecord からインスタンスが取得されます。関連するモデルの属性にアクセスすると、参照エラーが発生することは間違いありませんが、動的ファインダーは買収。

于 2013-07-02T20:48:52.300 に答える