2013-01-14 22 views
5

我正在使用Rails 3應用程序來允許人們申請贈款等。我們使用Elasticsearch/Tire作爲搜索引擎。用Elasticsearch/Tire展平多態AR關係

文檔,例如贈款提案,由許多不同類型的答案組成,如聯繫信息或散文。在AR,(在一般的關係DBS),你不能直接指定一個多態「的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來展示我的數據用於搜索和閱讀的更加健全的表示。在一個正常的輪胎設置中,我會得到(a)回答的索引和(b)敘述,聯繫人,多重選擇等的單獨索引。相反,我想只保存文檔和答案,可能作爲父母/孩子。 Answers索引將合併來自Answerings(id,question_id,updated_at ...)和Answerables(fname,lname,email ...)的數據。這樣,我可以從單個索引搜索答案,按類型,question_id,document_id等進行過濾。更新將從Answering中觸發,但每個答案都會從其答覆中提取信息。我使用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: [email protected], narrative_content: "Back in the day, when I was a teenager, before I had...", answerable_type: "narrative" } 

所以,我有幾個問題。

  1. 目標是爲所有答案提供單一查詢解決方案,而不管底層(可回答)類型。我以前從未設置過類似的東西。這似乎是對這個問題的理智方法嗎?你能預見我不能皺紋嗎?替代方案/建議的/ etc。受歡迎的。
  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會迴歸動態映射嗎? (我應該明確地映射將使用的每個字段?)

在此先感謝。請讓我知道,如果我可以更具體。

回答

0

索引是正確的方法。除索引字段名稱外,您還可以索引方法的結果。

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

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

索引值變成鴨子類型,所以如果您索引在視圖中引用的所有值,數據將可用。如果您訪問的索引項目模型沒有索引的屬性,它將從ActiveRecord獲取實例,如果您訪問相關模型的屬性,我很確定您會收到參考錯誤,但動態查找器可能會接管。