私は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" }
いくつか質問があります。
- 目標は、基になる (回答可能な) タイプに関係なく、すべての回答に対して単一のクエリ ソリューションを提供することです。私はこれまでにこのようなものを設定したことはありません。これは問題に対する正気のアプローチのように思えますか? シワは予測できない?代替案/提案/など 大歓迎です。
私が見ているように、トリッキーな部分はマッピングです。私の計画は、インデックス作成オプションが必要なフィールドの 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 は動的マッピングにフォールバックしますか? (使用されるすべてのフィールドを明示的にマップする必要がありますか?)
前もって感謝します。もっと具体的に教えてください。